Skip to content

Commit

Permalink
Added notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
Abhimanyu-dev committed Oct 29, 2024
1 parent a677b38 commit 012e6fb
Show file tree
Hide file tree
Showing 15 changed files with 496 additions and 24 deletions.
9 changes: 7 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ plugins {
id "kotlin-android"
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id "dev.flutter.flutter-gradle-plugin"
id 'com.google.gms.google-services'
}

def localProperties = new Properties()
Expand All @@ -24,7 +25,7 @@ if (flutterVersionName == null) {
}

android {
namespace = "com.example.attendance_app"
namespace = "com.pclub.attendance"
compileSdk = flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion

Expand All @@ -35,7 +36,7 @@ android {

defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "com.example.attendance_app"
applicationId = "com.pclub.attendance"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdk = flutter.minSdkVersion
Expand All @@ -56,3 +57,7 @@ android {
flutter {
source = "../.."
}
dependencies {
implementation platform('com.google.firebase:firebase-bom:33.5.1')
implementation 'com.google.firebase:firebase-analytics'
}
29 changes: 29 additions & 0 deletions android/app/google-services.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"project_info": {
"project_number": "788037853247",
"project_id": "attendance-338eb",
"storage_bucket": "attendance-338eb.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:788037853247:android:c1e473148d4ba293e7988a",
"android_client_info": {
"package_name": "com.pclub.attendance"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyATmGPGCnhEzncmC9lYhixCTn0jvXrhykA"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
}
],
"configuration_version": "1"
}
4 changes: 2 additions & 2 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.pclub.attendance">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:label="attendance_app"
android:label="Attendance App"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.example.attendance_app
package com.pclub.attendance

import io.flutter.embedding.android.FlutterActivity

Expand Down
4 changes: 4 additions & 0 deletions android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
plugins {
id 'com.google.gms.google-services' version '4.3.15' apply false
}

allprojects {
repositories {
google()
Expand Down
3 changes: 3 additions & 0 deletions android/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ pluginManagement {
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "7.3.0" apply false
// START: FlutterFire Configuration
id "com.google.gms.google-services" version "4.3.15" apply false
// END: FlutterFire Configuration
id "org.jetbrains.kotlin.android" version "2.0.0" apply false
}

Expand Down
1 change: 1 addition & 0 deletions firebase.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"flutter":{"platforms":{"android":{"default":{"projectId":"attendance-338eb","appId":"1:788037853247:android:c1e473148d4ba293e7988a","fileOutput":"android/app/google-services.json"}},"dart":{"lib/firebase_options.dart":{"projectId":"attendance-338eb","configurations":{"android":"1:788037853247:android:c1e473148d4ba293e7988a"}}}}}}
70 changes: 70 additions & 0 deletions lib/config/firebase.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'storage.dart';
import 'package:flutter/foundation.dart';
import 'package:hive/hive.dart';
import 'package:permission_handler/permission_handler.dart';
import 'localStorage.dart';
import 'notification.dart';
import 'firebase_options.dart';

class FirebaseConfig {
static Future<void> initialize() async {
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform
);
}

static void listenNotification() {
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
});
}

static Future<void> checkForInitialMessage() async {
RemoteMessage? initialMessage =
await FirebaseMessaging.instance.getInitialMessage();
}

static Future<PermissionStatus> _getNotificationsPermission() async {
var status = await Permission.notification.status;
if (!status.isGranted) {
final result = await Permission.notification.request();
return result;
} else {
return status;
}
}

static Future<void> registerNotification() async {
PermissionStatus status=await _getNotificationsPermission();
if(kDebugMode){
print(status);
}
var messaging = FirebaseMessaging.instance;
print("FCM TOKEN: ${await messaging.getToken()}");
NotificationSettings settings = await messaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
if (settings.authorizationStatus == AuthorizationStatus.authorized) {
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
LocalStorage.addNotification(message.notification!.toMap());
NotificationConfig.showNotification(message);
});
}
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
}
@pragma('vm:entry-point')
static Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
Firebase.initializeApp();
await Storage.initialize();
if(Hive.box("localStorage").isOpen){
LocalStorage.addNotification(message.notification!.toMap());
}
}
}
62 changes: 62 additions & 0 deletions lib/config/firebase_options.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// File generated by FlutterFire CLI.
// ignore_for_file: type=lint
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
import 'package:flutter/foundation.dart'
show defaultTargetPlatform, kIsWeb, TargetPlatform;

/// Default [FirebaseOptions] for use with your Firebase apps.
///
/// Example:
/// ```dart
/// import 'firebase_options.dart';
/// // ...
/// await Firebase.initializeApp(
/// options: DefaultFirebaseOptions.currentPlatform,
/// );
/// ```
class DefaultFirebaseOptions {
static FirebaseOptions get currentPlatform {
if (kIsWeb) {
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for web - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
}
switch (defaultTargetPlatform) {
case TargetPlatform.android:
return android;
case TargetPlatform.iOS:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for ios - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.macOS:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for macos - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.windows:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for windows - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.linux:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for linux - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
default:
throw UnsupportedError(
'DefaultFirebaseOptions are not supported for this platform.',
);
}
}

static const FirebaseOptions android = FirebaseOptions(
apiKey: 'AIzaSyATmGPGCnhEzncmC9lYhixCTn0jvXrhykA',
appId: '1:788037853247:android:c1e473148d4ba293e7988a',
messagingSenderId: '788037853247',
projectId: 'attendance-338eb',
storageBucket: 'attendance-338eb.appspot.com',
);
}
30 changes: 30 additions & 0 deletions lib/config/localStorage.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import 'dart:convert';
import 'package:hive/hive.dart';

class LocalStorage {
static final _localStorage = Hive.box('localStorage');
static addNotification(notification){
var rawData=_localStorage.get("notifications");
if(rawData!=null){
List previousNotifications= jsonDecode(rawData);
previousNotifications.add(notification);
_localStorage.put("notifications",jsonEncode(previousNotifications));
}
else{
List emptyNotifications=[];
emptyNotifications.add(notification);
_localStorage.put("notifications",jsonEncode(emptyNotifications));
}
}

static getNotifications(){
var rawData=_localStorage.get("notifications");
if(rawData!=null){
return jsonDecode(rawData);
}
else{
return [];
}
}

}
61 changes: 61 additions & 0 deletions lib/config/notification.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import 'dart:convert';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:http/http.dart' as http;
class NotificationConfig {
static final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
static const AndroidNotificationChannel channel = AndroidNotificationChannel(
'pclub-notification',
'pclub-ui-notification',
description: 'This channel is used for important notifications.',
importance: Importance.max,
);
static Future initialize(context) async {
var androidInitialize =
const AndroidInitializationSettings('mipmap/ic_noti');
var initializationsSettings =
InitializationSettings(android: androidInitialize);
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
await flutterLocalNotificationsPlugin.initialize(initializationsSettings);
}

static Future showNotification(RemoteMessage message) async {
late AndroidNotificationDetails androidPlatformChannelSpecifics;
if(message.notification!.android!.imageUrl!=null && message.notification!.android!.imageUrl!=""){
final http.Response response = await http.get(Uri.parse(message.notification!.android!.imageUrl!));
BigPictureStyleInformation bigPictureStyleInformation =
BigPictureStyleInformation(
ByteArrayAndroidBitmap.fromBase64String(base64Encode(response.bodyBytes)),
largeIcon: ByteArrayAndroidBitmap.fromBase64String(base64Encode(response.bodyBytes)),
);
androidPlatformChannelSpecifics = AndroidNotificationDetails(
channel.id,
channel.name,
playSound: true,
icon: "mipmap/ic_noti",
importance: Importance.max,
priority: Priority.max,
styleInformation: bigPictureStyleInformation,
largeIcon: ByteArrayAndroidBitmap.fromBase64String(
base64Encode(response.bodyBytes))
);
}else{
androidPlatformChannelSpecifics = AndroidNotificationDetails(
channel.id,
channel.name,
playSound: true,
icon: "mipmap/ic_noti",
importance: Importance.max,
priority: Priority.max
);
}

var not = NotificationDetails(android: androidPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.show(0,message.notification!.title , message.notification!.body, not,
payload: jsonEncode(message.data));
}
}
8 changes: 8 additions & 0 deletions lib/config/storage.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import 'package:hive_flutter/hive_flutter.dart';

class Storage {
static Future<void> initialize() async {
await Hive.initFlutter();
await Hive.openBox('localStorage');
}
}
10 changes: 10 additions & 0 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'package:attendance_app/config/firebase.dart';
import 'package:attendance_app/config/storage.dart';
import 'package:attendance_app/screens/user_dashboard.dart';
import 'package:attendance_app/screens/admin_dashboard.dart';
import 'package:attendance_app/screens/user_events.dart';
Expand All @@ -12,8 +14,16 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'dart:async';

import 'package:permission_handler/permission_handler.dart';

Future<void> main() async {
fillData();
WidgetsFlutterBinding.ensureInitialized();
await FirebaseConfig.initialize();
FirebaseConfig.listenNotification();
FirebaseConfig.registerNotification();
FirebaseConfig.checkForInitialMessage();
Storage.initialize();
runApp(const MyApp()); // Use MyApp directly
}

Expand Down
Loading

0 comments on commit 012e6fb

Please sign in to comment.