Skip to content

Instantly share code, notes, and snippets.

@oligazar
Last active November 13, 2020 11:12
Show Gist options
  • Save oligazar/38a8498b6981e965119cf0a83dfae86d to your computer and use it in GitHub Desktop.
Save oligazar/38a8498b6981e965119cf0a83dfae86d to your computer and use it in GitHub Desktop.
class Application : FlutterApplication() {
override fun onCreate() {
super.onCreate()
LocationService.setPluginRegistrant(object: PluginRegistry.PluginRegistrantCallback {
override fun registerWith(registry: PluginRegistry?) {
registry?.registrarFor("us.kostenko.gps_service_plugin.GpsServicePlugin")?.let {
GpsServicePlugin.registerWith(it)
}
}
})
// If you have onBackgroundMessage static callback in Dart - you need this
// otherwise you'll get Unhandled Exception: PlatformException(error, PluginRegistrantCallback is not set., null)
FlutterFirebaseMessagingService.setPluginRegistrant { registry ->
Log.d("Application", "FlutterFirebaseMessagingService.registerWith")
FirebaseCloudMessagingPluginRegistrant.registerWith(registry)
}
}
}

To integrate firebase_messaging plugin into the iOS part of your app, follow these steps:

1. Setup APNs

(Apple Push Notification service)

  • APNs key. (Used by FCM to send Push Notifications to the app identified by the App ID)
    • Create a new one here or use existing one:
      • Click the Add (+) button and enter a description for the APNs Auth Key.
      • Select the APNs checkbox
      • Click Confirm and then Download. Save your key (sertificate?) in a secure place (*.p8).
      • Note: this is a one-time download, and the key cannot be retrieved later.
    • Take note of the Key ID.
  • Create an App ID here or use existing one
    • Click the + button and select App IDs radio button
    • Select iOS, tvOS, watchOS under Platform
    • Input a Description for your App ID (e.g. Firebase Sample App)
    • Select Explicit App ID, then input your Bundle ID (e.g. com.google.samples.firebaseexample). The value of the Bundle ID should match the value that you are using in your app's Info.plist and the value that you are using to get a configuration for FCM
    • In the Capabilities section, make sure that Push Notifications is checked.
    • Take not of the Team ID (App ID Prefix)
    • Click Continue and Register to create the App ID.
  • A provisioning profile for that App ID (Can skip this section?). You need one for each app you want to publish. Note: it has an expiry date.
    • Create one for your app here.
    • Select App Store under Distribution, then select your existing App ID.
    • Return to the profiles dashboard and check that your app has platform iOS and type App Store.
    • Download and install double clicking on it.

2. Firebase

  • Using the Firebase Console add an iOS app to your project: Follow the assistant, download the generated GoogleService-Info.plist file, open ios/Runner.xcworkspace with Xcode, and within Xcode place the file inside ios/Runner.
  • Don't follow the steps named Add Firebase SDK and Add initialization code in the Firebase assistant.

3. XCode

  • In Xcode, select Runner in the Project Navigator. In the Capabilities Tab turn on Push Notifications and Background Modes,
  • Bnder Background Modes enable Background fetch and Remote notifications.

4. Upload APNs to Firebase Console

  • Inside your project in the Firebase console, select the gear icon, select Project Settings, and then select the Cloud Messaging tab.
  • In APNs authentication key under iOS app configuration, click the Upload button
  • Browse to the location where you saved your key, select it, and click Open. Add the key ID for the key and Team ID for your App ID, then click Upload

5. Code

  • Add the following lines to the func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool method in the AppDelegate.swift of your iOS project:

if #available(iOS 10.0, *) { UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate }

  • Flutter integration:

`@override void initState() { _configureMessaging(); super.initState(); }

Future _configureMessaging() async { _firebaseMessaging.configure( onMessage: (Map<String, dynamic> message) async { print("onMessage: $message"); }, onLaunch: (Map<String, dynamic> message) async { print("onLaunch: $message"); }, onResume: (Map<String, dynamic> message) async { print("onResume: $message"); }, ); _firebaseMessaging.requestNotificationPermissions( const IosNotificationSettings(sound: true, badge: true, alert: true)); _firebaseMessaging.onIosSettingsRegistered .listen((IosNotificationSettings settings) { print("Settings registered: $settings"); }); _firebaseMessaging.getToken().then((String token) async { print("Push Messaging getToken token: $token"); }); _firebaseMessaging.onTokenRefresh.listen((token) { print("Push Messaging onTokenRefresh token: $token"); }); }`

CHECKLIST

TEAM ID

Take note of your Team ID (available at https://developer.apple.com/account/#/membership/).

APN AUTH KEY

You need only one for all the apps. Available at https://developer.apple.com/account/resources/authkeys/list (section keys). If you don't have one, create it and don't forget to enable the push notification. It is downloadable only at the time of creation, so don't lose it and keep it in a safe place. It's a file with .p8 extension.

Take note of the Key ID.

PROVISIONING PROFILE

You need one for each app you want to publish. Remember that it has an expiry date. Available at https://developer.apple.com/account/resources/profiles/list (section profiles). Create one for your app. Select "App Store" under Distribution, then select your existing App ID. Download and install double clicking on it. Return to the profiles dashboard and check that your app has platform "iOS" and type "App Store".

FIREBASE CONSOLE

Create a project if you don't have one. Click on the gear on the left, then "Project Settings", then "General" tab. Click "Add App", "iOS", set your "ID bundle iOS" exactly equal to the App ID of the previous step. Add also your Team ID. Go to the next step, download the GoogleService-Info.plist, and follow the instructions on how add it to Xcode (drag and drop from Xcode is mandatory). Steps from "add Firebase SDK" and following are not mandatory.

Click on the gear on the left, then "Project Settings", then "Cloud Messaging" tab. Take note of the Server Key: it will be used for sending notification from code. In the "iOS app configuration", click on your app, then upload your p8 certicate you downloaded from "Auth key for APN" step.

XCODE

Be sure you have GoogleService-Info.plist under the Runner directory.

On tab "Signing & Capabilities", target "Runner", add the "Push Notification" capability. You should see it is now added, double check it is called "Push Notifications" and not "Push Notifications (something else)". Once added, check that a file with extension ".entitlements" is created under Runner directory. It is not important that the contents has "development" value, it will be automatically converted in "production" once you archive. Triple check that the provisioning profile specified in the "Provisioning Profile" file used is exactly the one you created earlier, specially if you select "Automatically manage signing" option.

In Runner/Info.plist be sure you don't have any "firebase*" key entries (unless you know what are you doing) In Runner/AppDelegate.swift (or .m) be sure you don't have the "if #available(iOS 10.0, *)" statement (unless you know what are you doing).

APP

At the time of writing, the notification works with the following version of the plugin, that you need to add in pubspec.yaml:

firebase_messaging: ^6.0.9

As for the code, there is no particular advice, you can follow the official tutorial. Remember to subscribe to a topic. When you send a notification use the same topic and the server key of the "firebase console" step. The notification fileds I use are: title, body, click_action 'FLUTTER_NOTIFICATION_CLICK', and priority: '10'

NOTIFIC='{ "notification": { "body": "this is a body", "title": "this is a title" }, "priority": "high", "data": { "click_action": "FLUTTER_NOTIFICATION_CLICK", "id": "1", "status": "done" }, "to": "<\FCM TOKEN>" }'

DATA='{ "priority": "high", "data": { "click_action": "FLUTTER_NOTIFICATION_CLICK", "id": "1", "status": "done" }, "to": "<FCM TOKEN>" }'

curl https://fcm.googleapis.com/fcm/send -H "Content-Type:application/json" -X POST -d "$DATA" -H "Authorization: key=<FCM SERVER KEY>"

FCM SERVER KEY = AAAAMRe4dkE:APA91bHffjQIIEJbcYkiqMx7VKfmxAkISUVrX0Wj2kBG9ZVqlLdnC-St6Zi6w6HkIKeya3DPvoDEqdljh24-5hH31cUywA2gOZOzLLbN07OB47HbmpuVl1z9mfgqgIgV8f8VRPMD0Nqz

MissingPluginException: No implementation found for method

FlutterEnginePluginRegistry: Attempted to detach plugins from an Activity

io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin

Custom PluginRegistrant example

Isolate/Garage example

Conflicts with other plugins

Supporting the new Android plugins APIs

Проблемы с firebase_messaging

Если запустить Android/Flutter - после рестарта апп перестает получать DataMessage

Если запустить Android/Android - все работает

LocationService & FirebaseMassaging работают по очереди нормально, даже после сворачивания приложения

После рестарта приложения onMessage работает только раз, после сворачивания не работает и onMessage и onBackgroundMessage

Может быть просто не использовать onBackgroundMessage для этого проекта?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment