[Solved] Heads up notification with Cloud Functions - Flutter

Question

Asked by GTF on December 30, 2021 (source).

I've configured my flutter app in order to receive push notifications, when I try from FCM it works properly and I obtain Heads up notification when the app is in foreground/background/closed.

I configured also the channel and all works.

The problem is when I want to send an automatic notification by using of Google Cloud Function, I never receive the heads up notificationn.

below my code:

Main.Dart

void main() async{
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  FirebaseMessaging.onBackgroundMessage(backgroundHandler);
  runApp(...) }

...

@override
  void initState() {
    LocalNotificationService.initialize(changeMessage);

    /// gives you the message on which user taps and it oened app from terminated state
    FirebaseMessaging.instance.getInitialMessage().then((event) {
      setState(() {
        widget.message = event!.data["route"];
      });
    });
    //foreground
    FirebaseMessaging.onMessage.listen((event) {
      print(event.notification?.body);
      print(event.notification?.title);
      LocalNotificationService.display(event);
    });

    // app in background but opened and user taps on notification
    FirebaseMessaging.onMessageOpenedApp.listen((event) {
      setState(() {
        widget.message = event!.data["route"];
      });
      /*final routeFromMessage =  event.data["route"];
      print(routeFromMessage);
      Navigator.of(context).pushNamed(routeFromMessage);*/
    });

  }
 

in Manifest I have:

<meta-data
                android:name="com.google.firebase.messaging.default_notification_channel_id"
                android:value = "myChannel"
                />

I created Service

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

class LocalNotificationService{

  static final FlutterLocalNotificationsPlugin _notificationsPlugin= FlutterLocalNotificationsPlugin();

  static void initialize(Function updateRoute){
    final InitializationSettings initializationSettings =
    InitializationSettings(android: AndroidInitializationSettings("@mipmap/ic_launcher"));

    _notificationsPlugin.initialize(initializationSettings,onSelectNotification: (String? route) async{
    updateRoute(route);
    });
  }
 static void display(RemoteMessage remoteMessage) async{
    try {
      final id = DateTime.now().millisecondsSinceEpoch ~/1000;
      final NotificationDetails notificationDetails = NotificationDetails(
        android: AndroidNotificationDetails(
          "myChannel",
          "myChannel channel",
          importance: Importance.max,
          priority: Priority.high
        )
      );
      
      await _notificationsPlugin.show(
          id, remoteMessage.notification!.title, remoteMessage.notification!.body, notificationDetails,payload: remoteMessage.data["route"]);
    } on Exception catch (e) {
      print(e);
    }
 }
}

and my Cloud Function:

const functions = require("firebase-functions");
const admin = require("firebase-admin");

admin.initializeApp(functions.config().functions);


exports.messageTrigger = functions.firestore.document('events/{likedId}').onCreate(async (snap,context) => { 
    console.log('----------------start function--------------------')
    const doc = snap.data()
    console.log(doc)
    const idFrom = doc.idFrom //chi mette like
    const idTo = doc.idTo //creatore evento
    const activity = doc.activity
    console.log(`Recupero il TO`)
    const res = await admin
      .firestore()
      .collection('users')
      .where('uid', '==', idTo)
      .get()
      .then(querySnapshot => {
        querySnapshot.forEach(userTo => {
          console.log(`Found user to: "${userTo.data().surname}"`)
          console.log(`Recupero il FROM`)
          if (userTo.data().pushToken) {
            // Get info user from (sent)

           admin
              .firestore()
              .collection('users')
              .where('uid', '==', idFrom)
              .get()
              .then(querySnapshot2 => {
                querySnapshot2.forEach(userFrom => {
                  console.log(`Found user from: ${userFrom.data().name}`)
                  const payload = {
                    notification: {
                      title: ...,
                      body: ...,
                      channel_id: "myChannel",
                    },
                    data: {route: ...}
                  }
                  // Let push to the target device
                 admin
                    .messaging()
                    .sendToDevice(userTo.data().pushToken, payload)
                    .then(response => {
                      console.log('Successfully sent message:', response)
                    })
                    .catch(error => {
                      console.log('Error sending message:', error)
                    })
                })
              })
          } else {
            console.log('Can not find pushToken target user')
          }
        })
      })
    return null
});
// // Create and Deploy Your First Cloud Functions
// // https://firebase.google.com/docs/functions/write-firebase-functions
//
// exports.helloWorld = functions.https.onRequest((request, response) => {
//   functions.logger.info("Hello logs!", {structuredData: true});
//   response.send("Hello from Firebase!");
// });

How I can solve,

thanks

Answer

Question answered by GTF (source).

For future readers I solve it by using of android_channel_id: "myChannel" instead of channel_id: "myChannel" in my cloud function

Video Answers on YouTube

ANDROID FIREBASE-CLOUD-MESSAGING FLUTTER GOOGLE-CLOUD-FIRESTORE GOOGLE-CLOUD-FUNCTIONS
SHARE: