skip to Main Content

I am building a Flutter app with Firebase Firestore, Cloud Functions and Messaging. I am trying to send and receive notifications.

The notifications work when:

  • The app is in the foreground and I create a new document in my collection (the one listened by the cloud function)
  • The app is in the foreground and I use the firebase console from the website
  • The app is in the background (but still working) when I use the firebase console

But, the notifications don’t work when:

  • The app is in the background and I create a new document in my collection
  • The app is terminated. I don’t receive notifications neither from the console, nor from the Cloud Function.

I have setup Firebase Functions like this:

import { messaging } from "firebase-admin";
import * as functions from "firebase-functions";
const { initializeApp } = require('firebase-admin/app');

initializeApp();

const token = "<my-token>";

exports.pushNotifications = functions
    .region('europe-central2')
    .firestore.document("signals/{docId}").onCreate(
        (snapshot) => {
            return messaging().send(
                {
                    token: token,
                    data: {
                        title: "A New Notification",
                        body: "Hello world!",
                    }
                }
            );
        }
    );

And on the front end:

class Notifications {
  static final messagingInstance = FirebaseMessaging.instance;

  static final Stream<RemoteMessage> foregroundNotificationsStream = FirebaseMessaging.onMessage;

  static final StreamSubscription<RemoteMessage> notificationsListener =
      FirebaseMessaging.onMessage.listen((RemoteMessage message) {
    if (message.data.isNotEmpty) {
      String body = '';
      try {
        final payload = message.data['body'];
        if (payload is String) body = payload;
      } catch (e) {
        body = '';
      }
      // Show dialog
    } else if (message.notification != null && message.notification!.body != null) {
      // show dialog
    }
  });

  static void getToken() async {
    await messagingInstance.requestPermission();
    final fcmToken = await messagingInstance.getToken();
    Get.put(User()).updateAppUser(tokenStatus: fcmToken);
    Database.updateDBUser();
  }
}

in the manifest:

    <intent-filter>
        <action android:name="FLUTTER_NOTIFICATION_CLICK" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</activity>
<meta-data
    android:name="firebase_messaging_auto_init_enabled"
    android:value="false" />
<meta-data
    android:name="firebase_analytics_collection_enabled"
    android:value="false" />

2

Answers


  1. Chosen as BEST ANSWER

    I fixed it by adding:

    notification: {
       title: title,
       body: description,
      },
    

    to the send() function. So now it looks like this:

      return messaging().send(
            {
                notification: {
                    title: 'Hello',
                    body: 'World',
                },
                token: listTokens.length === 1 ? listTokens[0] : listTokens,
                data: {
                    title: 'Hello',
                    body: 'World',
                },
            }
        );
    

  2. Add background message handler.

    @pragma('vm:entry-point')
    Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
      // TODO
    }
    
    void main() {
      FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
      runApp(MyApp());
    }
    

    See Background messages for details.

    Use getInitialMessage to get a message when a user clicks notification to open the application from terminated state.

    RemoteMessage? initialMessage = await FirebaseMessaging.instance.getInitialMessage();
    if (initialMessage != null) {
      // TODO
    }
    

    See Handling interaction for details.

    Send a combined message (data and notification) to provide the same data in all the application states or a data message in which case the application is responsible to show a visible notification.

    const payload = {
      notification: {
        title: "A New Notification",
        body: "Hello world!",
      },
      data: {
        title: "A New Notification",
        body: "Hello world!",
      }
    };
    

    See Message types for details.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search