Skip to content

Commit

Permalink
Push notifications part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
Codel1417 committed May 6, 2024
1 parent a96e06b commit b233e08
Show file tree
Hide file tree
Showing 12 changed files with 298 additions and 45 deletions.
6 changes: 5 additions & 1 deletion android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
id "com.google.gms.google-services"
}

def localProperties = new Properties()
Expand Down Expand Up @@ -32,6 +33,7 @@ android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
coreLibraryDesugaringEnabled true
}

kotlinOptions {
Expand Down Expand Up @@ -80,8 +82,10 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:${localProperties.getProperty('kotlin.version')}"
implementation "com.polidea.rxandroidble2:rxandroidble:1.18.1"
testImplementation 'junit:junit:4.13.2'

implementation 'com.google.gms:google-services:4.4.1'
// https://developer.android.com/jetpack/androidx/releases/test/#1.2.0
androidTestImplementation 'androidx.test:runner:1.5.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'

}
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": "530304958306",
"project_id": "tail-app-408901",
"storage_bucket": "tail-app-408901.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:530304958306:android:f6fa9441549b1656b2b63b",
"android_client_info": {
"package_name": "com.codel1417.tail_app"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyDce_fr8SP1W8NiOQtMvvGX4UgLEs1qiXI"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
}
],
"configuration_version": "1"
}
11 changes: 10 additions & 1 deletion android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@
<meta-data
android:name="flutterEmbedding"
android:value="2" />

<meta-data
android:name="firebase_analytics_collection_enabled"
android:value="false" />
<meta-data
android:name="firebase_messaging_auto_init_enabled"
android:value="true" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="newsletter" />
</application>

</manifest>
1 change: 0 additions & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ allprojects {
mavenCentral()
}
}

rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
Expand Down
2 changes: 1 addition & 1 deletion android/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version '8.3.2' apply false
id "org.jetbrains.kotlin.android" version "1.9.23" apply false

id("com.google.gms.google-services") version "4.4.1" apply false
}

include ":app"
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":"tail-app-408901","appId":"1:530304958306:android:f6fa9441549b1656b2b63b","fileOutput":"android/app/google-services.json"}},"dart":{"lib/firebase_options.dart":{"projectId":"tail-app-408901","configurations":{"android":"1:530304958306:android:f6fa9441549b1656b2b63b","ios":"1:530304958306:ios:6b58cfb4dd10b9b6b2b63b"}}}}}}
96 changes: 96 additions & 0 deletions lib/Backend/firebase.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:logging/logging.dart';

final fireLogger = Logger('Firebase');

@pragma('vm:entry-point')
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
fireLogger.info("Handling a background message: ${message.messageId}");
}

Future<void> initFirebase() async {
fireLogger.info("Begin init Firebase");
await Firebase.initializeApp();
FirebaseMessaging messaging = FirebaseMessaging.instance;
messaging.app.setAutomaticDataCollectionEnabled(false);
FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);
await messaging.subscribeToTopic("newsletter");
final notificationSettings = await messaging.requestPermission(
provisional: true,
sound: false,
);
NotificationSettings settings = await messaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: false,
);
FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
fireLogger.info('Got a message whilst in the foreground!');
fireLogger.info('Message data: ${message.data}');

if (message.notification != null) {
fireLogger.info('Message also contained a notification: ${message.notification}');
const AndroidNotificationDetails androidNotificationDetails = AndroidNotificationDetails(
'newsletter',
'Newsletter',
channelDescription: 'Notifications from the Tail Company Newsletter',
priority: Priority.low,
playSound: false,
enableVibration: false,
enableLights: false,
);
const NotificationDetails notificationDetails = NotificationDetails(android: androidNotificationDetails);
await flutterLocalNotificationsPlugin?.show(
message.notification.hashCode,
message.notification?.title,
message.notification?.body,
notificationDetails,
);
}
});
}

Future<String?> getFirebaseToken() async {
return await (FirebaseMessaging.instance).getToken();
}

FlutterLocalNotificationsPlugin? flutterLocalNotificationsPlugin;

Future<void> initNotificationPlugin() async {
flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
// initialise the plugin. app_icon needs to be a added as a drawable resource to the Android head project
const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings("@mipmap/ic_launcher");
const DarwinInitializationSettings initializationSettingsDarwin = DarwinInitializationSettings(defaultPresentSound: false, requestSoundPermission: false);
const InitializationSettings initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsDarwin,
);
await flutterLocalNotificationsPlugin?.initialize(
initializationSettings,
onDidReceiveNotificationResponse: onDidReceiveNotificationResponse,
onDidReceiveBackgroundNotificationResponse: onDidReceiveBackgroundNotificationResponse,
);
}

//Foreground
void onDidReceiveNotificationResponse(NotificationResponse notificationResponse) async {
final String? payload = notificationResponse.payload;
if (notificationResponse.payload != null) {
fireLogger.info('notification payload: $payload');
}
}

//background
@pragma('vm:entry-point')
void onDidReceiveBackgroundNotificationResponse(NotificationResponse notificationResponse) {
final String? payload = notificationResponse.payload;
if (notificationResponse.payload != null) {
fireLogger.info('notification payload: $payload');
}
}
12 changes: 12 additions & 0 deletions lib/Frontend/pages/developer/developer_menu.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:logging_flutter/logging_flutter.dart';
import 'package:sentry_hive/sentry_hive.dart';
import 'package:tail_app/Backend/firebase.dart';

import '../../../Backend/Bluetooth/bluetooth_manager.dart';
import '../../../Backend/Definitions/Device/device_definition.dart';
Expand Down Expand Up @@ -134,6 +136,16 @@ class _DeveloperMenuState extends ConsumerState<DeveloperMenu> {
},
),
),
FutureBuilder(
future: getFirebaseToken(),
builder: (BuildContext context, AsyncSnapshot<String?> snapshot) {
return ListTile(
onTap: () => Clipboard.setData(ClipboardData(text: snapshot.hasData ? snapshot.data! : "")),
title: const Text('Firebase'),
subtitle: Text(snapshot.hasData ? snapshot.data! : ""),
);
},
),
ListTile(
title: Text(
"Gear Debug",
Expand Down
69 changes: 69 additions & 0 deletions lib/firebase_options.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// 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:
return ios;
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: 'AIzaSyDce_fr8SP1W8NiOQtMvvGX4UgLEs1qiXI',
appId: '1:530304958306:android:f6fa9441549b1656b2b63b',
messagingSenderId: '530304958306',
projectId: 'tail-app-408901',
storageBucket: 'tail-app-408901.appspot.com',
);

static const FirebaseOptions ios = FirebaseOptions(
apiKey: 'AIzaSyCTapi53i9GlNLzAo5DTeghb2uXWfSrHXg',
appId: '1:530304958306:ios:6b58cfb4dd10b9b6b2b63b',
messagingSenderId: '530304958306',
projectId: 'tail-app-408901',
storageBucket: 'tail-app-408901.appspot.com',
iosBundleId: 'com.codel1417.tailApp',
);

}
14 changes: 4 additions & 10 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import 'dart:async';
import 'dart:io';

import 'package:feedback_sentry/feedback_sentry.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flex_color_scheme/flex_color_scheme.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
Expand All @@ -21,6 +20,7 @@ import 'package:tail_app/Backend/action_registry.dart';

import 'Backend/Bluetooth/bluetooth_manager.dart';
import 'Backend/Definitions/Action/base_action.dart';
import 'Backend/firebase.dart';
import 'Backend/move_lists.dart';
import 'Backend/plausible_dio.dart';
import 'Backend/sensors.dart';
Expand All @@ -30,7 +30,7 @@ import 'constants.dart';

//late SharedPreferences prefs;

FutureOr<SentryEvent?> beforeSend(SentryEvent event, {Hint? hint}) async {
FutureOr<SentryEvent?> beforeSend(SentryEvent event, Hint hint) async {
bool reportingEnabled = SentryHive.box(settings).get("allowErrorReporting", defaultValue: true);
if (reportingEnabled) {
if (kDebugMode) {
Expand All @@ -48,14 +48,6 @@ const String domain = "tail-app";
late final Plausible plausible;
final mainLogger = Logger('Main');

Future<void> initFirebase() async {
final notificationSettings = await FirebaseMessaging.instance.requestPermission(provisional: true);
final apnsToken = await FirebaseMessaging.instance.getAPNSToken();
if (apnsToken != null) {
// APNS token is available, make FCM plugin API requests...
}
}

Future<void> main() async {
Logger.root.level = Level.ALL;
mainLogger.info("Begin");
Expand All @@ -67,6 +59,8 @@ Future<void> main() async {
mainLogger.fine("Init Hive");
await initHive();
//initDio();
await initFirebase();
await initNotificationPlugin();
mainLogger.fine("Init Sentry");
await SentryFlutter.init(
(options) async {
Expand Down
Loading

0 comments on commit b233e08

Please sign in to comment.