使用 Firebase 函数向 Android 应用发送通知

Posted

技术标签:

【中文标题】使用 Firebase 函数向 Android 应用发送通知【英文标题】:Send notifications to android app using Firebase Functions 【发布时间】:2020-05-31 14:00:30 【问题描述】:

我正在开发一个聊天应用程序,因此我需要发送已收到新消息的通知。 为此,我使用 Firebase 函数。 我正在使用 sendToDevice 功能,它需要一个 token 来发送通知。问题是,我似乎无法检索发送消息的用户的令牌。 这是我的 .js 代码:

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

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

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


exports.sendNotification = functions.database.ref("/chats/id/messages/messageId/content")
.onWrite((change,context) => 
    var content = change.after.val();

    var payload = 
        data:
            title: "Stranger has sent you a message",
            text: content
        
    ;

    // Here I need to the ID of the person who sent the message
    // And then compare this Id with the two Ids of the to users that are in the conversation
    // If the two Ids are different, then save the other Id as the token
    // So that I can send a notification to the other user.
    const senderId = database.ref("/chats/id/messages/id/sender/senderId");



    admin.messaging().sendToDevice(senderId, payload)
    .then(function(response)
        console.log("Successfully sent message: ", response);
        return null;
    )
    .catch(function(error)
        console.log("Error sending message: ", error);
    )
);

如您所见,我正在检查 messages/content 子项中的任何更改。 这就是我的通知内容。

然后,我正在尝试检索消息发件人 ID,以便知道是谁发送了消息并检索其他用户 ID 以通知他

这可能有点令人困惑,所以这是我的 Firebase 实时数据库

我做错了什么,所以这段代码可以正常工作?这是我在 android 中接收消息的活动:

class MyFirebaseInstanceId : FirebaseMessagingService() 
    override fun onMessageReceived(p0: RemoteMessage) 
        if(p0.data.size > 0)
            val payload :Map<String, String> = p0.data

            sendNotification(payload)

        
    

    private fun sendNotification(payload: Map<String, String>) 
        val builder = NotificationCompat.Builder(this)
        builder.setSmallIcon(R.drawable.common_google_signin_btn_icon_disabled)
        builder.setContentTitle(payload.get("username"))
        builder.setContentText(payload.get("email"))

        val intent = Intent(this, MainActivity::class.java)
        val stackBuilder = TaskStackBuilder.create(this)

        stackBuilder.addNextIntent(intent)

        val resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)

        builder.setContentIntent(resultPendingIntent)

        val notificationManager =  (getSystemService(Context.NOTIFICATION_SERVICE)) as NotificationManager

        notificationManager.notify(0, builder.build())
    

【问题讨论】:

请注意,使用database.ref("/chats/id/messages/id/sender/senderId"),您获取的不是字段值,而是Reference。您需要使用once() 方法。另外注意需要返回admin.messaging().sendToDevice(senderId, payload)...,见firebase.google.com/docs/functions/terminate-functions @RenaudTarnec 你能给我一个如何使用.once()函数的例子吗?这解决了我的问题,我想给你一个绿色的复选标记。 【参考方案1】:

按照上面我们的 cmets,这里是如何在您的 Cloud Function 中使用 once()val() 方法:

//.....
const refSenderId = database.ref("/chats/id/messages/id/sender/senderId");

return refSenderId.once('value')
 .then(dataSnapshot =>  
     const senderId = dataSnapshot.val();
     return admin.messaging().sendToDevice(senderId, payload)
 )
.then(function(response)
    console.log("Successfully sent message: ", response);
    return null;
)
.catch(function(error)
    console.log("Error sending message: ", error);
    return null;   // <- Note the return here.
)
//.....

【讨论】:

谢谢!快速提问,我可以在其中使用另一个 .once() 来检索另一个值吗? 是的,但是您需要正确链接异步方法返回的不同承诺。 developer.mozilla.org/en-US/docs/Web/javascript/Guide/… 和 firebase.google.com/docs/functions/terminate-functions。您可以在问题底部添加您的新代码(通过编辑问题),如果您愿意,我会对其进行审核。

以上是关于使用 Firebase 函数向 Android 应用发送通知的主要内容,如果未能解决你的问题,请参考以下文章

使用 firebase 向 android 设备发送免费推送通知的限制或成本是多少

使用 php 向 android 应用程序发送推送通知,无需像 firebase 这样的外部云

Laravel API - 使用 Firebase FCM 向 android 和 iOS 客户端应用程序发送通知

如何使用firebase在android studio中从一个用户向另一个用户发送通知[重复]

带有推送通知的深层链接 - FCM - Android

如何根据 Firebase 数据库中的条目向我的 android 应用发送通知? [关闭]