0
votes

Is it possible to send FCM notifications through Firebase Cloud Functions, when a Firestore data field changes, but for a website, not an app. There is lots of guidance out there for Android and iOS but nothing for simply web apps, outside of sending notifications from the Firebase Console).

I've been trying to find out how to trigger a notification from Cloud Functions but can't find anything useful.

As an example, my database has the following structure:

  • Collection: users
  • Documents: documents named using userID
  • Data Fields: Fields 1 through 5. Field 5 stores the FCM Token. Field 1 stores their status (online, offline, offline pending messages).

I would like to ensure that when Data Field 1 changes (to 'offline pending messages), that the relevant user gets notified (based on the Doc ID).

Edit: adding code below for reference

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNotification = functions.database.ref('/users/{doc}/{Hears}')
    .onUpdate(async (change, context) => {

        const db = admin.firestore();
        db.collection('users').doc(context.params.userId)  // get userId
        .get()
        .then(doc => {
            //this is intended to get the FCM token stored in the user's document
           const fcmToken = doc.data().usrTkn;
           // Notification details
            const payload = {
            notification: {
                title: 'You have a new message.',
                body: 'Open your app'
            }
        };
     })
    //This should send a notification to the user's device when web app is not in focus. 
    //FCM is set up in service worker
     const response = await admin.messaging().sendToDevice(fcmToken, payload);
     console.log(response);

    });
1

1 Answers

1
votes

Sending messages to a web app is no different from sending it to a native mobile app, so the sending part of guidance you've found is equally applicable. The Firebase documentation even contains an example of sending notifications on a Realtime Database trigger, and doing the same for Firestore would not be much different.

If you're having a specific problem sending messages, I recommend showing what you tried, and what isn't working about it.


Update: your code doesn't work (no matter what sort of device you send the notification to), because you're not handling the asynchronous nature of get() in your code.

The simplest way to fix that is to use await there too, just like you do when calling sendToDevice. So:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNotification = functions.database.ref('/users/{doc}/{Hears}')
    .onUpdate(async (change, context) => {
        const db = admin.firestore();
        const doc = await db.collection('users').doc(context.params.userId).get();
        const fcmToken = doc.data().usrTkn;
        const payload = {
          notification: {
            title: 'You have a new message.',
            body: 'Open your app'
          }
        };
        const response = await admin.messaging().sendToDevice(fcmToken, payload);
        console.log(response);
    })

I highly recommend spending some time on learning about asynchronous calls, closures, async/await, and how to debug something like this by adding logging.