Search code examples
androidflutterfirebase-cloud-messaging

FCM onBackgroundMessage doesn't work on terminated state


I'm implementing notifications in Android.

I want the notification to trigger a Dialog in app when pressed, on the Foreground I had no problems showing it, I then used FirebaseMessaging.onMessageOpenedApp for Background state and it worked as well.

Since both FirebaseMessaging.onMessageOpenedApp and FirebaseMessaging.onBackgroundMessage were triggered when a notification was pressed in Background state I decided to not use FirebaseMessaging.onMessageOpenedApp and stick with FirebaseMessaging.onBackgroundMessage.

I'm aware that onBackgroundMessage must be isolated and can't modify any UI logic, so I decided to call an API to check a flag "hasNotification" in my database. Said so the method onBackgroundMessage gets triggered very few times in Background state and never gets triggered in Terminated state (both in my emulator and in my device) I don't know if I'm missing something.

I'm sending notifications through Firebase Messaging panel.

import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import '../../../globals.dart' as globals;

import 'init.dart';
import 'package:gluten_free_demo/api/glt_insert_notification.dart';

Future<dynamic> _firebaseMessagingBackgroundHandler(
    RemoteMessage message) async {

  globals.notification['title'] = message.notification?.title;
  globals.notification['body'] = message.notification?.body;
  
  insertNotification(true);
  print("Handling background message, ${globals.notification}");
}

void main(List<String> args) async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  await FirebaseMessaging.instance.getInitialMessage();
  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);

  runApp(const Init());
}

Solution

  • Document says the background message handler:

    1. When using Flutter version 3.3.0 or higher, the message handler must be annotated with @pragma('vm:entry-point') right above the function declaration (otherwise it may be removed during tree shaking for release mode).

    I am guessing that you using Flutter version 3.3.0 or higher, So you have to add @pragma('vm:entry-point') at the top of handler.

    @pragma('vm:entry-point')
    Future<dynamic> _firebaseMessagingBackgroundHandler(
        RemoteMessage message) async {
    
      globals.notification['title'] = message.notification?.title;
      globals.notification['body'] = message.notification?.body;
      
      insertNotification(true);
      print("Handling background message, ${globals.notification}");
    }