Firebase function to fetch data from Firebase DB to make Push notification

I have chat app with firebase database and Firebase cloud messaging. I can send firebase notification via console but in real scenario it should be automatic. To make automatic notification,My friend wrote Index.js (Added in cloud functions) file for me but its not sending notifications.

As per our logic function should trigger whenever there is any new entries (in any node or in any room) and fetch these values by firebase function and make post request to FCM server to make notification to receiver device (get value of receiver device from token_To).

  • Message
  • Message_From
  • Time
  • Type
  • token_To
  • Firebase数据库结构

    Index.js

    var functions = require('firebase-functions');
    var admin = require('firebase-admin');
    
    
    var serviceAccount = require('./demofcm-78aad-firebase-adminsdk-4v1ot-2764e7b580.json');
    admin.initializeApp({
      credential: admin.credential.cert(serviceAccount),
      databaseURL: "https://demofcm-78aad.firebaseio.com/"
    })
    
    // // Create and Deploy Your First Cloud Functions
    // // https://firebase.google.com/docs/functions/write-firebase-functions
    //
    // exports.helloWorld = functions.https.onRequest((request, response) => {
    //  response.send("Hello from Firebase!");
    // });
    exports.setUserNode = functions.auth.user().onCreate(event => {
      // ...
    });
    
    exports.notifyMsg = functions.database.ref('/{chatroom}/{mid}/')
        .onWrite(event => {
    
           if (!event.data.val()) {
             return console.log('Message Deleted');
           }
    
           const getDeviceTokensPromise = admin.database().ref('/{chatroom}/{mid}/token_to').once('value');
    
    
           return Promise.all([getDeviceTokensPromise]).then(results => {
             const tokensSnapshot = results[0];
    
             if (!tokensSnapshot.hasChildren()) {
               return console.log('There are no notification tokens to send to.');
             }
    
             const payload = {
               notification: {
                 title: 'You have a new Message!',
                 body: event.data.val().Message
               }
             };
    
             const tokens = Object.keys(tokensSnapshot.val());
    
             return admin.messaging().sendToDevice(tokens, payload).then(response => {
    
               const tokensToRemove = [];
               response.results.forEach((result, index) => {
                 const error = result.error;
                 if (error) {
                   console.error('Failure sending notification to', tokens[index], error);
    
                   if (error.code === 'messaging/invalid-registration-token' ||
                       error.code === 'messaging/registration-token-not-registered') {
                     tokensToRemove.push(tokensSnapshot.ref.child(tokens[index]).remove());
                   }
                 }
               });
               return Promise.all(tokensToRemove);
             });
           });
    });
    

    Firebase function Log

    Firebase云功能日志

    How can i fetch above mentioned values of any newly added node in same room(9810012321-9810012347) or any other room(9810012321-9810012325) from database and send it to FCM to make notification

    Thanks in Advance.


    What i did is created a Message node and I believe doing this by users key. ie, having the receiver(toId) and sender (fromId) key to send the notification. Hope it helps.

    Firebase消息节点

    exports.sendMessageNotification = functions.database.ref('/messages/{pushId}')
    .onWrite(event => {
        let message = event.data.current.val();
        console.log('Fetched message', event.data.current.val());
        let senderUid = message.fromId;
        let receiverUid = message.toId;
        let promises = [];
    
        console.log('message fromId', receiverUid);
        console.log('catch me', admin.database().ref(`/users/${receiverUid}`).once('value'));
    
        if (senderUid == receiverUid) {
            //if sender is receiver, don't send notification
            //promises.push(event.data.current.ref.remove());
            return Promise.all(promises);
        }
    
        let messageStats = message.messageStatus;
        console.log('message Status', messageStats);
    
        if (messageStats == "read") {
            return Promise.all(promises);
        }
    
        let getInstanceIdPromise = admin.database().ref(`/users/${receiverUid}/pushToken`).once('value');
        let getSenderUidPromise = admin.auth().getUser(senderUid);
    
        return Promise.all([getInstanceIdPromise, getSenderUidPromise]).then(results => {
            let instanceId = results[0].val();
            let sender = results[1];
            console.log('notifying ' + receiverUid + ' about ' + message.text + ' from ' + senderUid);
            console.log('Sender ', sender);
            var badgeCount = 1;
            let payload = {
                notification: {
                    uid: sender.uid,
                    title: 'New message from' + ' ' + sender.displayName,
                    body: message.text,
                    sound: 'default',
                    badge: badgeCount.toString()
                },
                'data': { 
                    'notificationType': "messaging", 
                    'uid': sender.uid
              }
            };
            badgeCount++;
            admin.messaging().sendToDevice(instanceId, payload)
                .then(function (response) {
                    console.log("Successfully sent message:", response);
                })
                .catch(function (error) {
                    console.log("Error sending message:", error);
                });
        });
    });
    

    const getDeviceTokensPromise = event.data.child('token_To');
    

    should be there instated of getting data from database reference.

    or

    with fixed path without wildcard like below

    const getDeviceTokensPromise = admin.database().ref('/${chatroom}/${mid}/token_to').once('value');
    

    where chatroom and mid is variable which contain value

    Second thing:

    if (!tokensSnapshot.exists()) { 
    

    should in replace of

    if (!tokensSnapshot.hasChildren()) {
    

    third thing:

    I am not sure about push notification tokenId but is it required to do?

    const tokens = Object.keys(tokensSnapshot.val());

    may be we can use directly like below to send push notification

    const tokens = tokensSnapshot.val();


     let payload = {
            notification: {
                uid: sender.uid,
                title: 'New message from' + ' ' + sender.displayName,
                body: message.text,
                sound: 'default',
                badge: badgeCount.toString()
            },
            'data': { 
                'notificationType': "messaging", 
                'uid': sender.uid
          }
        };
    

    There are two types of FCMs. 1) Data 2) Notification

    For detailed overview : FCM Reference

    You have to fix your payload for both FCMS. And for Data FCM you have to extract Data in your FCM Service (Client) and generate a push notification according to your need.

    链接地址: http://www.djcxy.com/p/40976.html

    上一篇: 我如何在Woocommerce Rest API中获得Tokenization密钥?

    下一篇: Firebase功能从Firebase DB获取数据以进行推送通知