diff --git a/apps/amiapp_flutter/android/app/google-services.json b/apps/amiapp_flutter/android/app/google-services.json index 6db61a5..10ef6f7 100644 --- a/apps/amiapp_flutter/android/app/google-services.json +++ b/apps/amiapp_flutter/android/app/google-services.json @@ -5,6 +5,42 @@ "storage_bucket": "remote-habits.appspot.com" }, "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:1001564516023:android:a021e40983dfcc781a2732", + "android_client_info": { + "package_name": "com.cio.unit" + } + }, + "oauth_client": [ + { + "client_id": "1001564516023-59nace30peq2pfenpruv72hkbma4ocfd.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyASGdGzS1zfpzNdZTXtthSWEHs3b0mmOGA" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "1001564516023-59nace30peq2pfenpruv72hkbma4ocfd.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "1001564516023-4ec1vok624lq3sg3lu8mc8gbtn07bkbn.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "io.customer.rn-sample.fcm" + } + } + ] + } + } + }, { "client_info": { "mobilesdk_app_id": "1:1001564516023:android:7cfa09512576cfdb1a2732", @@ -31,10 +67,10 @@ "client_type": 3 }, { - "client_id": "1001564516023-5n3nd9b1d58s4pb776qpld55vuvrk45u.apps.googleusercontent.com", + "client_id": "1001564516023-4ec1vok624lq3sg3lu8mc8gbtn07bkbn.apps.googleusercontent.com", "client_type": 2, "ios_info": { - "bundle_id": "io.customer.ios-sample.cocoapods-fcm" + "bundle_id": "io.customer.rn-sample.fcm" } } ] @@ -67,10 +103,10 @@ "client_type": 3 }, { - "client_id": "1001564516023-5n3nd9b1d58s4pb776qpld55vuvrk45u.apps.googleusercontent.com", + "client_id": "1001564516023-4ec1vok624lq3sg3lu8mc8gbtn07bkbn.apps.googleusercontent.com", "client_type": 2, "ios_info": { - "bundle_id": "io.customer.ios-sample.cocoapods-fcm" + "bundle_id": "io.customer.rn-sample.fcm" } } ] @@ -103,10 +139,82 @@ "client_type": 3 }, { - "client_id": "1001564516023-5n3nd9b1d58s4pb776qpld55vuvrk45u.apps.googleusercontent.com", + "client_id": "1001564516023-4ec1vok624lq3sg3lu8mc8gbtn07bkbn.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "io.customer.rn-sample.fcm" + } + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:1001564516023:android:0b41c62a5570b80f1a2732", + "android_client_info": { + "package_name": "io.customer.android.sample.java_layout" + } + }, + "oauth_client": [ + { + "client_id": "1001564516023-59nace30peq2pfenpruv72hkbma4ocfd.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyASGdGzS1zfpzNdZTXtthSWEHs3b0mmOGA" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "1001564516023-59nace30peq2pfenpruv72hkbma4ocfd.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "1001564516023-4ec1vok624lq3sg3lu8mc8gbtn07bkbn.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "io.customer.rn-sample.fcm" + } + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:1001564516023:android:52a211f8e5cf7b431a2732", + "android_client_info": { + "package_name": "io.customer.android.sample.kotlin_compose" + } + }, + "oauth_client": [ + { + "client_id": "1001564516023-59nace30peq2pfenpruv72hkbma4ocfd.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyASGdGzS1zfpzNdZTXtthSWEHs3b0mmOGA" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "1001564516023-59nace30peq2pfenpruv72hkbma4ocfd.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "1001564516023-4ec1vok624lq3sg3lu8mc8gbtn07bkbn.apps.googleusercontent.com", "client_type": 2, "ios_info": { - "bundle_id": "io.customer.ios-sample.cocoapods-fcm" + "bundle_id": "io.customer.rn-sample.fcm" } } ] @@ -139,10 +247,82 @@ "client_type": 3 }, { - "client_id": "1001564516023-5n3nd9b1d58s4pb776qpld55vuvrk45u.apps.googleusercontent.com", + "client_id": "1001564516023-4ec1vok624lq3sg3lu8mc8gbtn07bkbn.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "io.customer.rn-sample.fcm" + } + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:1001564516023:android:2835273f9d64bb631a2732", + "android_client_info": { + "package_name": "io.customer.rn_sample.fcm" + } + }, + "oauth_client": [ + { + "client_id": "1001564516023-59nace30peq2pfenpruv72hkbma4ocfd.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyASGdGzS1zfpzNdZTXtthSWEHs3b0mmOGA" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "1001564516023-59nace30peq2pfenpruv72hkbma4ocfd.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "1001564516023-4ec1vok624lq3sg3lu8mc8gbtn07bkbn.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "io.customer.rn-sample.fcm" + } + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:1001564516023:android:bce0de5f8642156a1a2732", + "android_client_info": { + "package_name": "io.customer.rn_sample.typescript" + } + }, + "oauth_client": [ + { + "client_id": "1001564516023-59nace30peq2pfenpruv72hkbma4ocfd.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyASGdGzS1zfpzNdZTXtthSWEHs3b0mmOGA" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "1001564516023-59nace30peq2pfenpruv72hkbma4ocfd.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "1001564516023-4ec1vok624lq3sg3lu8mc8gbtn07bkbn.apps.googleusercontent.com", "client_type": 2, "ios_info": { - "bundle_id": "io.customer.ios-sample.cocoapods-fcm" + "bundle_id": "io.customer.rn-sample.fcm" } } ] diff --git a/apps/amiapp_flutter/ios/Podfile b/apps/amiapp_flutter/ios/Podfile index 1b80559..1802b8f 100644 --- a/apps/amiapp_flutter/ios/Podfile +++ b/apps/amiapp_flutter/ios/Podfile @@ -40,7 +40,7 @@ target 'Runner' do use_modular_headers! # Uncomment only 1 of the lines below to install a version of the iOS SDK - pod 'CustomerIO/MessagingPushFCM', '~> 2' # install production build + pod 'CustomerIO/MessagingPushFCM', '~> 2.11' # install production build # install_non_production_ios_sdk_local_path(local_path: '~/code/customerio-ios/', is_app_extension: false, push_service: "fcm") # install_non_production_ios_sdk_git_branch(branch_name: 'name-of-ios-sdk-branch', is_app_extension: false, push_service: "fcm") @@ -50,7 +50,7 @@ end target 'NotificationServiceExtension' do use_frameworks! # Uncomment only 1 of the lines below to install a version of the iOS SDK - pod 'CustomerIO/MessagingPushFCM', '~> 2' # install production build + pod 'CustomerIO/MessagingPushFCM', '~> 2.11' # install production build # install_non_production_ios_sdk_local_path(local_path: '~/code/customerio-ios/', is_app_extension: true, push_service: "fcm") # install_non_production_ios_sdk_git_branch(branch_name: 'name-of-ios-sdk-branch', is_app_extension: true, push_service: "fcm") end diff --git a/apps/amiapp_flutter/ios/Runner.xcodeproj/project.pbxproj b/apps/amiapp_flutter/ios/Runner.xcodeproj/project.pbxproj index 3b15f41..fd3d87f 100644 --- a/apps/amiapp_flutter/ios/Runner.xcodeproj/project.pbxproj +++ b/apps/amiapp_flutter/ios/Runner.xcodeproj/project.pbxproj @@ -7,11 +7,11 @@ objects = { /* Begin PBXBuildFile section */ + 0888D1012BEC428D66F8D1ED /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 6615E32455EADFC1FBDD78CC /* GoogleService-Info.plist */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 28EF97E17CEA8AA8F34B77F4 /* Pods_NotificationServiceExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F682EA52D3CECA56F5B31766 /* Pods_NotificationServiceExtension.framework */; }; 3006373429A1011F00D63963 /* Env.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3006373329A1011F00D63963 /* Env.swift */; }; 3006373529A1011F00D63963 /* Env.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3006373329A1011F00D63963 /* Env.swift */; }; - 302D7E2C295BEC44005CBB29 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 302D7E2B295BEC44005CBB29 /* GoogleService-Info.plist */; }; 302D7E34295BEE78005CBB29 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 302D7E33295BEE78005CBB29 /* NotificationService.swift */; }; 302D7E38295BEE78005CBB29 /* NotificationServiceExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 302D7E31295BEE78005CBB29 /* NotificationServiceExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; @@ -61,11 +61,11 @@ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 3006373329A1011F00D63963 /* Env.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Env.swift; sourceTree = ""; }; 30095F29295BC58F00D3389F /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; }; - 302D7E2B295BEC44005CBB29 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 302D7E31295BEE78005CBB29 /* NotificationServiceExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = NotificationServiceExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 302D7E33295BEE78005CBB29 /* NotificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = ""; }; 302D7E35295BEE78005CBB29 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 6615E32455EADFC1FBDD78CC /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 78A3A48B351662F042A03F84 /* Pods-NotificationServiceExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NotificationServiceExtension.release.xcconfig"; path = "Target Support Files/Pods-NotificationServiceExtension/Pods-NotificationServiceExtension.release.xcconfig"; sourceTree = ""; }; @@ -149,6 +149,7 @@ 97C146EF1CF9000F007C117D /* Products */, 3E9C772F68D2059B32B4A97E /* Pods */, B5A766D2ED4D4067A36F2D1D /* Frameworks */, + 6615E32455EADFC1FBDD78CC /* GoogleService-Info.plist */, ); sourceTree = ""; }; @@ -164,7 +165,6 @@ 97C146F01CF9000F007C117D /* Runner */ = { isa = PBXGroup; children = ( - 302D7E2B295BEC44005CBB29 /* GoogleService-Info.plist */, 30095F29295BC58F00D3389F /* Runner.entitlements */, 97C146FA1CF9000F007C117D /* Main.storyboard */, 97C146FD1CF9000F007C117D /* Assets.xcassets */, @@ -285,9 +285,9 @@ files = ( 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, - 302D7E2C295BEC44005CBB29 /* GoogleService-Info.plist in Resources */, 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + 0888D1012BEC428D66F8D1ED /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/apps/amiapp_flutter/ios/Runner/AppDelegate.swift b/apps/amiapp_flutter/ios/Runner/AppDelegate.swift index 4394c42..eb425b0 100644 --- a/apps/amiapp_flutter/ios/Runner/AppDelegate.swift +++ b/apps/amiapp_flutter/ios/Runner/AppDelegate.swift @@ -13,21 +13,19 @@ import FirebaseCore ) -> Bool { GeneratedPluginRegistrant.register(with: self) - FirebaseApp.configure() + // Depending on the method you choose to install Firebase in your app, + // you may need to add functions to this file, such as the following: + // FirebaseApp.configure() + // + // Be sure to read the official Firebase docs to correctly install Firebase in your app. + + Messaging.messaging().delegate = self CustomerIO.initialize(siteId: Env.siteId, apiKey: Env.apiKey, region: .US) { config in config.autoTrackDeviceAttributes = true config.logLevel = .debug } - - // Set FCM messaging delegate - Messaging.messaging().delegate = self - - let center = UNUserNotificationCenter.current() - center.delegate = self - - // Register for push notification - UIApplication.shared.registerForRemoteNotifications() + MessagingPushFCM.initialize(configOptions: nil) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } @@ -40,31 +38,6 @@ import FirebaseCore override func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { MessagingPush.shared.application(application, didFailToRegisterForRemoteNotificationsWithError: error) } - - override func userNotificationCenter( - _ center: UNUserNotificationCenter, - didReceive response: UNNotificationResponse, - withCompletionHandler completionHandler: @escaping () -> Void - ) { - let handled = MessagingPush.shared.userNotificationCenter(center, didReceive: response, - withCompletionHandler: completionHandler) - - // If the Customer.io SDK does not handle the push, it's up to you to handle it and call the - // completion handler. If the SDK did handle it, it called the completion handler for you. - if !handled { - completionHandler() - } - } - - // OPTIONAL: If you want your push UI to show even with the app in the foreground, override this function and call - // the completion handler. - override func userNotificationCenter( - _ center: UNUserNotificationCenter, - willPresent notification: UNNotification, - withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void - ) { - completionHandler([.alert, .badge, .sound]) - } } extension AppDelegate: MessagingDelegate { diff --git a/apps/amiapp_flutter/ios/firebase_app_id_file.json b/apps/amiapp_flutter/ios/firebase_app_id_file.json new file mode 100644 index 0000000..a1b7d31 --- /dev/null +++ b/apps/amiapp_flutter/ios/firebase_app_id_file.json @@ -0,0 +1,7 @@ +{ + "file_generated_by": "FlutterFire CLI", + "purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory", + "GOOGLE_APP_ID": "1:1001564516023:ios:6688d08503fde0491a2732", + "FIREBASE_PROJECT_ID": "remote-habits", + "GCM_SENDER_ID": "1001564516023" +} \ No newline at end of file diff --git a/apps/amiapp_flutter/lib/firebase_options.dart b/apps/amiapp_flutter/lib/firebase_options.dart new file mode 100644 index 0000000..915bb4a --- /dev/null +++ b/apps/amiapp_flutter/lib/firebase_options.dart @@ -0,0 +1,69 @@ +// File generated by FlutterFire CLI. +// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members +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: 'AIzaSyASGdGzS1zfpzNdZTXtthSWEHs3b0mmOGA', + appId: '1:1001564516023:android:ceccfaa92480cba51a2732', + messagingSenderId: '1001564516023', + projectId: 'remote-habits', + storageBucket: 'remote-habits.appspot.com', + ); + + static const FirebaseOptions ios = FirebaseOptions( + apiKey: 'AIzaSyApOVYacWweX4ab6a3rf8CmjqI4PmUvnEI', + appId: '1:1001564516023:ios:6688d08503fde0491a2732', + messagingSenderId: '1001564516023', + projectId: 'remote-habits', + storageBucket: 'remote-habits.appspot.com', + iosClientId: '1001564516023-uv71nhj8ca3vo1imcsmvfl8vjmlgml92.apps.googleusercontent.com', + iosBundleId: 'io.customer.amiapp.flutter', + ); +} diff --git a/apps/amiapp_flutter/lib/main.dart b/apps/amiapp_flutter/lib/main.dart index 00304f1..37a402c 100644 --- a/apps/amiapp_flutter/lib/main.dart +++ b/apps/amiapp_flutter/lib/main.dart @@ -4,8 +4,26 @@ import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'src/app.dart'; import 'src/auth.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:firebase_messaging/firebase_messaging.dart'; +import 'firebase_options.dart'; + void main() async { WidgetsFlutterBinding.ensureInitialized(); + + // Initialize FCM (flutter-fire) + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ); + + /// Update the iOS foreground notification presentation options to allow + /// heads up notifications. + await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions( + alert: true, + badge: true, + sound: true, + ); + // Load SDK configurations await dotenv.load(fileName: ".env"); // Wait for user state to be updated diff --git a/apps/amiapp_flutter/lib/src/screens/dashboard.dart b/apps/amiapp_flutter/lib/src/screens/dashboard.dart index 83405b0..9997b70 100644 --- a/apps/amiapp_flutter/lib/src/screens/dashboard.dart +++ b/apps/amiapp_flutter/lib/src/screens/dashboard.dart @@ -1,7 +1,10 @@ import 'dart:async'; +import 'dart:developer'; import 'package:customer_io/customer_io.dart'; import 'package:customer_io/customer_io_inapp.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:permission_handler/permission_handler.dart'; @@ -53,6 +56,26 @@ class _DashboardScreenState extends State { inAppMessageStreamSubscription = CustomerIO.subscribeToInAppEventListener(handleInAppEvent); + + // Setup 3rd party SDK, flutter-fire. + // We install this SDK into sample app to make sure the CIO SDK behaves as expected when there is another SDK installed that handles push notifications. + FirebaseMessaging.instance.getInitialMessage().then((initialMessage) { + CustomerIO.track(name: "push clicked", attributes: {"push": initialMessage?.notification?.title, "app-state": "killed"}); + }); + + // ...while app was in the background (but not killed). + FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) { + CustomerIO.track(name: "push clicked", attributes: {"push": message.notification?.title, "app-state": "background"}); + }); + + // Important that a 3rd party SDK can receive callbacks when a push is received while app in background. + // + // Note: A push will not be shown on the device while app is in foreground. This is a FCM behavior, not a CIO SDK behavior. + // If you send a push using Customer.io with the FCM service setup in Customer.io, the push will be shown on the device. + FirebaseMessaging.onMessage.listen((RemoteMessage message) { + CustomerIO.track(name: "push received", attributes: {"push": message.notification?.title, "app-state": "foreground"}); + }); + super.initState(); } diff --git a/apps/amiapp_flutter/pubspec.yaml b/apps/amiapp_flutter/pubspec.yaml index 89504e2..bd2a01c 100644 --- a/apps/amiapp_flutter/pubspec.yaml +++ b/apps/amiapp_flutter/pubspec.yaml @@ -44,6 +44,8 @@ dependencies: permission_handler: ^10.2.0 flutter_dotenv: ^5.0.2 package_info_plus: ^4.0.2 + firebase_core: ^2.24.2 + firebase_messaging: ^14.7.9 dev_dependencies: flutter_test: