Función de Firebase para recuperar datos de Firebase DB para hacer notifications Push

Tengo una aplicación de chat con database firebase y posts en la nube de Firebase. Puedo enviar notifications de Firebase a través de la console, pero en un escenario real debería ser automático. Para hacer una notificación automática, My friend escribió el file Index.js (Añadido en las funciones de la nube) pero no está enviando notifications.

Según nuestra lógica, la function se activará cada vez que haya nuevas inputs (en cualquier nodo o habitación) y recupere estos valores mediante la function firebase y haga una request posterior al server FCM para notificar al dispositivo receptor (obtenga el valor del dispositivo receptor de token_To )

  1. Mensaje
  2. Mensaje de
  3. Hora
  4. Tipo
  5. token_To

Estructura de base de datos de 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({ cnetworkingential: admin.cnetworkingential.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-registenetworking') { tokensToRemove.push(tokensSnapshot.ref.child(tokens[index]).remove()); } } }); return Promise.all(tokensToRemove); }); }); }); 

Registro de la function de Firebase

Registro de la función de nube de Firebase

¿Cómo puedo get los valores mencionados anteriormente de cualquier nodo recién agregado en la misma habitación (9810012321-9810012347) o en cualquier otra habitación (9810012321-9810012325) desde la database y enviarlo a FCM para que realice la notificación?

Gracias por adelantado.

Lo que hice fue crear un nodo Mensaje y creo que hacerlo por la key de los usuarios. es decir, tener la key del receptor (toId) y del emisor (fromId) para enviar la notificación. Espero eso ayude.

Nodo de mensaje de 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'); 

debería estar allí para get datos de la reference de la database.

o

con ruta fija sin comodín como a continuación

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

donde chatroom y mid son variables que contienen valor

Segunda cosa:

 if (!tokensSnapshot.exists()) { 

debería en reemploop de

 if (!tokensSnapshot.hasChildren()) { 

tercera cosa:

No estoy seguro acerca de push notification tokenId, pero ¿es obligatorio?

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

puede ser que podemos utilizar directamente como a continuación para enviar notificación de inserción

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 } }; 

Hay dos types de FCM. 1) Datos 2) Notificación

Para una descripción detallada: reference de FCM

Tienes que arreglar tu carga útil para ambos FCMS. Y para Data FCM tiene que extraer datos en su service de FCM (cliente) y generar una notificación de inserción según su necesidad.