Skip to content

Instantly share code, notes, and snippets.

@chrispage1
Last active May 31, 2022 01:00
Show Gist options
  • Save chrispage1/9a3692ad85ba1f496cc2c70ddd943642 to your computer and use it in GitHub Desktop.
Save chrispage1/9a3692ad85ba1f496cc2c70ddd943642 to your computer and use it in GitHub Desktop.
Configuring Flutter application with Firebase

Installing Firebase Analytics

Requires the firebase_analytics package.

Android

Add packages to pubspec.yaml

  1. Under dependencies, add the Firebase Analytics package firebase_analytics: ^6.0.0
  2. Run flutter pub get to retrieve the package

Configure Android app in Firebase console

  1. Begin by adding an Android app.
  2. Set your Android package name, found in android/app/build.gradle under defaultConfig/applicationId
  3. Set the app nickname to something appropriate, e.g. 'Android App'
  4. Generate your debug signing certificate SHA-1
    1. Right click on android/app_android.iml and choose Flutter > Open for editing in Android Studio
    2. In the gradle inspection window expand Android / {$APP_NAME} / Tasks / android and open SigningReport
    3. Copy the SHA1 from the debugAndroidTest variant
    4. Paste this into Firebase console
  5. Hit next
  6. Download the generated google-services.json and paste into the android/app directory

Add Google Services SDK to android/build.gradle

  1. Within the buildscript / dependencies object, add classpath 'com.google.gms:google-services:4.3.3'

Add plugins to android/app/build.gradle

  1. After plugins are being applied (look for apply plugin:), add apply plugin: 'com.google.gms.google-services'
  2. Within the dependencies object, add implementation 'com.google.firebase:firebase-analytics:17.5.0'

Run your Android app to talk with Firebase!

iOS

Given that you've already pre-configured Android, iOS setup is fairly straightforward.

Configure iOS app in Firebase console

  1. Begin by adding an iOS app
  2. Enter your package name as the bundle ID, found in android/app/build.gradle under defaultConfig/applicationId
  3. Give it a nickname, e.g. 'iOS App'
  4. Download the configuration file

Configure your iOS application

  1. Open the ios/Runner.xcodeproj project in Xcode
  2. Drag the GoogleService-Info.plist file into the root of your application
  3. Check Copy items if needed and add to all targets

Run your iOS app to talk with Firebase!

Tracking PageRoute Transitions

To track PageRoute transitions, add a FirebaseAnalyticsObserver to the list of NavigatorObservers on your Navigator, e.g. if you're using a MaterialApp:

import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:firebase_analytics/observer.dart';

FirebaseAnalytics analytics = FirebaseAnalytics();

MaterialApp(
  home: MyAppHome(),
  navigatorObservers: [
    FirebaseAnalyticsObserver(analytics: analytics),
  ],
);

You can also track transitions within your PageRoute (e.g. when the user switches from one tab to another) by implementing RouteAware and subscribing it to FirebaseAnalyticsObserver. See [example/lib/tabs_page.dart][tabs_page] for an example of how to wire that up.

Setting up Cloud messaging

This section assumes you have already run through the Analytics phase of the app and have Google services implemented. Full documentation can be found here, but this is a summary to quickly implement cloud messaging.

Android

Add package to pubspec.yaml

  1. Under dependencies add the Firebase Cloud Messaging package firebase_messaging: ^7.0.0
  2. Run flutter pub get to retrieve the package

Configure AndroidManifest.xml

  1. Within android/app/src/main/AndroidManifest.xml under Manifest / Application / Activity node, add the following:
<intent-filter>
  <action android:name="FLUTTER_NOTIFICATION_CLICK" />
  <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

Run the application

  1. You may need to reinstall the application entirely to get notifications working.
  2. Once complete, send a test notification

Configure background messaging (optional)

  1. Within android/app/build.gradle add implementation 'com.google.firebase:firebase-messaging:20.2.4' to the dependencies node
  2. Create a new file called Application.kt underneath android/app/src/main/kotlin/${PACKAGE_ID}/
  3. Insert the below:
package com.example.app // change me

import io.flutter.app.FlutterApplication
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin
import io.flutter.view.FlutterMain
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService

class Application : FlutterApplication(), PluginRegistrantCallback {

    override fun onCreate() {
        super.onCreate()
        FlutterFirebaseMessagingService.setPluginRegistrant(this);
        FlutterMain.startInitialization(this)
    }

    override fun registerWith(registry: PluginRegistry?) {
        if (!registry!!.hasPlugin("io.flutter.plugins.firebasemessaging")) {
            FirebaseMessagingPlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
        }
    }
}
  1. Modify the android:name property within android/app/src/main/AndroidManifest.xml on the Manifest / Application / Activity node from .MainActivity to .Application

iOS

Configure application within Xcode

You will need a signing request which can be easily generated using the documentation here. Make sure to keep a copy of any certificates / APN's generated. You can use this CSR as many times as needed. I'd recommend your certificate name is the same as your app bundle, to avoid confusion.

  1. Open ios/Runner.xcodeproj within Xcode.
  2. Make sure the Runner application is selected in the left hand pane
  3. Go to 'Signing & Capabilities'
  4. Make sure the Automatically manage signing option is checked
  5. Choose the appropriate team you want to generate certificates using.
  6. Click the '+' underneath 'Signing & Capabilities' and double click 'Push notifications'
  7. Click the '+' again and chose 'Background Modes'. Within background modes, enable 'Background fetch' and 'Remote notifications'

Configure certificate

  1. Login to developer.apple.com
  2. Go to 'Certificates, IDs & Profiles
  3. Under identifiers, due to the previous step you should see your package identifier
  4. Go to 'Keys' and click the '+' icon
  5. Set your key name
  6. Check the 'Apple Push Notification service (APNs) option
  7. Hit Continue, verify the setup and then press Register
  8. Download your APN key (.p8) and keep it safe
  9. Take note of the 'Key ID' and your 'Team ID' (top right)
  10. Be sure to hit done, otherwise the next step will fail

Configure Firebase

  1. In the Firebase project, click the settings cog
  2. Navigate to 'Cloud Messaging'
  3. Click 'Upload' under 'APNs Authentication Key' in the 'iOS app configuration' section
  4. Choose your p8 file, enter your Key & Team ID
  5. Submit and you should be ready to send notifications note: push notifications will not work by default on simulator devices.

Handling remote messages

More information can be found on the official plugin page but basics are below.

final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();

// background message handler
Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async {
  if (message.containsKey('data')) {
    // Handle data message
    final dynamic data = message['data'];
  }

  if (message.containsKey('notification')) {
    // Handle notification message
    final dynamic notification = message['notification'];
  }

  // Or do other work.
}

// configure firebase messaging to handle
_firebaseMessaging.configure(

    // handle incoming messages.
    onMessage: (Map<String, dynamic> message) async {
      print("onMessage: $message");
      _showItemDialog(message);
    },
    
    // handle background messages
    onBackgroundMessage: myBackgroundMessageHandler,
    
    // perform actions based on a clicked message on app launch
    onLaunch: (Map<String, dynamic> message) async {
      print("onLaunch: $message");
      _navigateToItemDetail(message);
    },
    
    // perform actions based on a clicked message on app resume
    onResume: (Map<String, dynamic> message) async {
      print("onResume: $message");
      _navigateToItemDetail(message);
    },
  );

Requesting permission to send notifications

This is a requirement on iOS before messages can be received.

final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
_firebaseMessaging.requestNotificationPermissions()

Retrieve Firebase Instance Token

The Firebase instance token allows you to send targeted messaging to particular devices.

final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
_firebaseMessaging.getToken().then((String value) {
  var arr = value.split(':');
  var token = arr[0];
  
  print(token);
});

Creating a flutter project

## Use the flutter create command.

The eventual bundle ID will be the org value appended by a dot and then project-name.

For example, if you had a domain example.com and you wanted to create an eventual package id of com.example.myspecialapp you'd use the build options --project-name=myspecialapp --org=com.example

flutter create --project-name=app --platforms=ios,android --org="com.example" [outputDirectory]

## Modify the app name & description in pubspec.yaml

  1. At the top of your pubspec.yaml, set the desired project name & description.
  2. Within app/src/main/AndroidManifest.xml modify the android:label within the Manifest / Application node to your desired app name.
  3. For iOS, the app name can be opening the ios/Runner.xcodeproj in XCode and changing the Display Name
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment