使用Firebase云函数发送推送通知

27

我正在尝试制作一个云函数,向指定用户发送推送通知。

当用户进行一些更改时,数据将添加/更新到firebase数据库中的节点下(该节点表示用户ID)。在这里,我希望触发一个函数,向用户发送推送通知。

我在数据库中为用户设置了以下结构。

Users

 - UID
 - - email
 - - token

 - UID
 - - email
 - - token

到目前为止,我有这个函数:

exports.sendNewTripNotification = functions.database.ref('/{uid}/shared_trips/').onWrite(event=>{
const uuid = event.params.uid;

console.log('User to send notification', uuid);

var ref = admin.database().ref('Users/{uuid}');
ref.on("value", function(snapshot){
        console.log("Val = " + snapshot.val());
        },
    function (errorObject) {
        console.log("The read failed: " + errorObject.code);
});

当我获得回调时,snapshot.val()返回null。有什么办法可以解决这个问题吗?还有可能在之后如何发送推送通知?


控制台输出的 uuid 是否显示了正确的值? - Jen Person
是的,UUID 是正确的。 - Tudor Lozba
使用反引号替代 uuid 的值,例如:admin.database().ref(\Users/${uuid}`)。同时,应该使用 once()替代on()on()` 会一直监听变化,而这不是云函数所需要的。 - Bob Snyder
2
此外,您的函数应该返回一个承诺,告诉 Cloud Functions 您的工作已完成并且可以安全地清理。如果您没有返回承诺就进行异步工作,它将无法按照您想要的方式工作。建议观看这些视频教程以了解更多信息:https://www.youtube.com/playlist?list=PLl-K7zZEsYLkPZHe41m4jfAxUi0JjLgSM - Doug Stevenson
Doug是正确的 - 使用Cloud Functions时,您应该返回一个Promise,以便它可以观察链执行,然后在完成时停止实例。因为在这种情况下它无法知道异步工作正在发生,所以函数在异步工作实际完成之前就已经完成了。 - Andrew Breen
5个回答

40

我已经成功地实现了这个功能。以下是使用 Cloud Functions 发送通知的代码,这是对我有效的。

exports.sendNewTripNotification = functions.database.ref('/{uid}/shared_trips/').onWrite(event=>{
    const uuid = event.params.uid;

    console.log('User to send notification', uuid);

    var ref = admin.database().ref(`Users/${uuid}/token`);
    return ref.once("value", function(snapshot){
         const payload = {
              notification: {
                  title: 'You have been invited to a trip.',
                  body: 'Tap here to check it out!'
              }
         };

         admin.messaging().sendToDevice(snapshot.val(), payload)

    }, function (errorObject) {
        console.log("The read failed: " + errorObject.code);
    });
})

有没有办法使用Firebase云函数向主题发送消息? - Jerin A Mathews
这段代码会向所有用户发送通知吗?如果我只想向一个用户发送通知,就像 WhatsApp 消息通知一样,该怎么办? - Deepak Gautam
@DeepakGautam 这将仅发送到一个特定的设备。请注意,sendToDevice是一种遗留方法。请参阅https://firebase.google.com/docs/cloud-messaging/admin/send-messages。 - Codelicious
3
我正在使用上述云函数发送通知,但我不知道如何在iOS上接收。请问有人可以告诉我如何接收上述通知并将其内容显示给用户吗? - Arjun

9

回答Jerin A Mathews的问题: 使用主题发送消息:

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

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

//Now we're going to create a function that listens to when a 'Notifications' node changes and send a notificcation
//to all devices subscribed to a topic

exports.sendNotification = functions.database.ref("Notifications/{uid}")
.onWrite(event => {
    //This will be the notification model that we push to firebase
    var request = event.data.val();

    var payload = {
        data:{
          username: request.username,
          imageUrl: request.imageUrl,
          email: request.email,
          uid: request.uid,
          text: request.text
        }
    };

    //The topic variable can be anything from a username, to a uid
    //I find this approach much better than using the refresh token
    //as you can subscribe to someone's phone number, username, or some other unique identifier
    //to communicate between

    //Now let's move onto the code, but before that, let's push this to firebase

    admin.messaging().sendToTopic(request.topic, payload)
    .then((response) => {
        console.log("Successfully sent message: ", response);
        return true;
    })
    .catch((error) => {
        console.log("Error sending message: ", error);
        return false;
    })
})
//And this is it for building notifications to multiple devices from or to one.

你好,如果我想发送到特定的主题怎么办?比如,一些人订阅了“早安”主题,另一组人订阅了“午间”主题。请帮忙解决。 - Joseph Wambura
@Gsilveira,你能看一下这个吗?https://stackoverflow.com/questions/56656303/cloud-function-cant-log-anything - DevAS

1

返回此函数调用。

return ref.on("value", function(snapshot){
        console.log("Val = " + snapshot.val());
        },
    function (errorObject) {
        console.log("The read failed: " + errorObject.code);
});

这将使云函数保持活动状态,直到请求完成。请参考Doug在评论中提供的链接了解有关返回承诺的更多信息。

感谢大家的回答。将它们结合起来帮助我实现了我想要的! - Tudor Lozba
很高兴能帮到您解决问题,请接受答案。@TudorLozba - Aawaz Gyawali

1

在云函数中发送主题通知

主题基本上是您可以为所选组发送通知的群组。

    var topic = 'NOTIFICATION_TOPIC';
    const payload = {
        notification: {
            title: 'Send through Topic',
            body: 'Tap here to check it out!'
        }
   };

   admin.messaging().sendToTopic(topic,payload);

您可以从移动端为任何新或现有的主题注册设备。

谢谢,这个很好用!我该如何修改它?声音、标记等。 - submariner
尝试这个 - https://firebase.google.com/docs/cloud-messaging/http-server-ref#:%7E:text=Table%202c.%20Web%20(JavaScript)%20%E2%80%94%20keys%20for%20notification%20messages - Lahiru Pinto

0
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);


exports.sendNotificationToTopic = 
functions.firestore.document('Users/{uuid}').onWrite(async (event) => {

//let title = event.after.get('item_name');
//let content = event.after.get('cust_name');
var message = {
    notification: {
        title: "TGC - New Order Recieved",
        body: "A New Order Recieved on TGC App",
    },
    topic: 'orders_comming',
};

let response = await admin.messaging().send(message);
console.log(response);
});

对于向主题发送通知,上述代码对我来说运行良好,如果您有任何疑问,请告诉我。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接