skip to Main Content

I am using a cloud functions to send a fcm message to the admins phone every time the bookings collection has a new document here:

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

exports.sendBookingNotification = functions.firestore
    .document("bookings/{bookingId}")
    .onCreate(async (snapshot, context) => {
        // Get the newly added booking data
        const bookingData = snapshot.data();

        // Retrieve the admin's FCM token from Firestore
        const adminFCMToken = await getAdminFCMToken(); // Implement the function to get admin's FCM token

        if (adminFCMToken) {
            // Send a notification to the admin
            const message = {
                data: {
                    title: "New Booking",
                    body: `A new booking has been added: ${bookingData.serviceTitle}`,
                   
                },
                token: adminFCMToken,
                
            };
            console.log( `A new booking has been added: ${bookingData.serviceTitle}`);

            try {
                await admin.messaging().send(message);
                console.log("Notification sent successfully.");
            } catch (error) {
                console.error("Error sending notification:", error);
            }
        }
    });

// Function to get the admin's FCM token from Firestore
async function getAdminFCMToken() {
    try {
        const adminDoc = await admin.firestore().collection("users").where("userType", "==", "admin").get();

        if (!adminDoc.empty) {
            // Assuming there's only one admin, so we retrieve the first document found
            const adminData = adminDoc.docs[0].data();
            console.log("Admin Data:", adminData);


            // Check if the admin document has an "fcmtoken" field
            if (adminData.fcmToken) { // Update field name here
                return adminData.fcmToken; // Update field name here
            } else {
                console.error("Admin document does not have an FCM token.");
                return null;
            }
        } else {
            console.error("No admin found in Firestore.");
            return null;
        }
    } catch (error) {
        console.error("Error fetching admin FCM token:", error);
        return null;
    }
}

And I am receiving the message here:

//making notifications available when the app closed
Future<void> handleBackgroundMessage(RemoteMessage message) async {
  // Access title and body directly from message.data
  final title = message.data['title'];
  final body = message.data['body'];

  print('Title: $title');
  print('Body: $body');
  print('Payload: ${message.data}');
}

class DBHandler {
  //instance of firebase authentication
  final FirebaseAuth auth = FirebaseAuth.instance;

  //instance of firebase messenging
  final _firebaseMessaging = FirebaseMessaging.instance;

  //Function to initialise Notifications
  Future<void> initNotification() async {
    //request persmission from user
    await _firebaseMessaging.requestPermission();

    generateDeviceToken();

    FirebaseMessaging.onBackgroundMessage(handleBackgroundMessage);
    // Save the FCM token to the user's Firestore document
  }

  generateDeviceToken() async {
    String? fcmToken = await FirebaseMessaging.instance.getToken();
    final userId = FirebaseAuth.instance.currentUser!.uid;
    await FirebaseFirestore.instance
        .collection('users')
        .doc(userId)
        .update({'fcmToken': fcmToken});
  }

I am Receiving the payload correctly the title and body are printing but I am still getting no notification showing up on my physical device.

2

Answers


  1. message.notification is only populated when you send a notification type message from the console. When you send from the Admin SDK, it is a data type message instead with a data payload.

    Read more about message types in the documentation to better understand the difference between these two message types.

    If you want the title and body fields of the data payload you created, you should work only with message.data.

    Login or Signup to reply.
  2. It seems like you have not setup any code for a notification to show up – the most popular way to do this is using this package flutter_local_notifications

    In your handleBackgroundMessage function you would use the above package, for example:

     _flutterLocalNotificationsPlugin.show(
        message.data.hashCode,
        message.data['title'],
        message.data['body'],
        NotificationDetails(
          android: AndroidNotificationDetails(
            _androidChannel.id,
            _androidChannel.name,
            _androidChannel.description,
            importance: Importance.max,
            priority: Priority.high,
         ),
      ),
      payload: message.data,
    );
    

    You can check out this tutorial to setup the above

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