【问题标题】:How to send notification for each incoming message in firebase (React js)?如何为firebase(React js)中的每条传入消息发送通知?
【发布时间】:2021-10-07 19:30:01
【问题描述】:

我有一个简单的聊天网络应用程序,两个人可以在其中互相交谈。我希望他们在收到新消息时收到通知。到目前为止,我设法获得了用户的许可并获得了令牌:

const messaging = firebase.messaging();
function InitializeFirebaseMessaging(){
  messaging.requestPermission().then(function(){
    console.log("Notification permission");
    return messaging.getToken();
  }).then(function(token){
    console.log("Token: "+token);
  }).catch(function (reason){
    console.log(reason);
  });
}
messaging.onMessage(function (payload){
  console.log(payload);
});
messaging.onTokenRefresh(function () {
  messaging.getToken()
      .then(function (newtoken) {
          console.log("New Token : "+ newtoken);
      })
      .catch(function (reason) {
          console.log(reason);
      })
});

在 Firestore 中,我有一个“配对”集合,我将用户配对(因此只有配对才能相互发送消息),并且每个用户都有一个包含他们发送和接收消息的集合。

当我登录 Firebase 时,转到参与/云消息传递,我可以使用令牌从 Firebase 向该用户发送消息。如何实现每条传入消息自动向对方发送通知?

【问题讨论】:

    标签: javascript reactjs firebase push-notification firebase-cloud-messaging


    【解决方案1】:

    如果您想自动发送消息,则需要为每次聊天设置新消息的云函数侦听器。当写入新消息时,使用该云功能向接收消息的用户发送 FCM 消息。

    Here 是我如何在我的一个应用程序中使用 RTDB 侦听器执行此操作的示例:

    import * as functions from 'firebase-functions'
    import admin from 'firebase-admin'
    
    export default functions
      .region('europe-west1')
      .database.ref('/user_chat_messages/{senderUid}/{receiverUid}/{messageUid}')
      .onCreate(async (eventSnapshot, context) => {
        const { timestamp, params } = context
        const { senderUid, receiverUid, messageUid } = params
    
        if (context.authType === 'ADMIN') {
          return null
        }
    
        const snapValues = eventSnapshot.val()
        const {
          message = '',
          link,
          image,
          location,
          audio,
          authorUid,
          created,
          authorPhotoUrl,
        } = snapValues
        let lastMessage = message
        const senderRef = admin.database().ref(`/users/${senderUid}`).once('value')
    
        const senderSnap = await admin
          .database()
          .ref(`/users/${senderUid}`)
          .once('value')
    
        const receiverSnap = await admin
          .database()
          .ref(`/users/${receiverUid}`)
          .once('value')
    
        const {
          displayName: senderName = null,
          photoURL: senderPhoto = null,
        } = senderSnap.val()
        const {
          displayName: receiverName = null,
          photoURL: receiverPhoto = null,
        } = receiverSnap.val()
    
        if (!message) {
          if (link) {
            lastMessage = 'Link'
          }
          if (image) {
            lastMessage = 'Photo'
          }
          if (location) {
            lastMessage = 'Position'
          }
          if (audio) {
            lastMessage = 'Audio'
          }
        }
    
        // receiver chat message
        await admin
          .database()
          .ref(`/user_chat_messages/${receiverUid}/${senderUid}/${messageUid}`)
          .update(snapValues)
    
        // sender chat message
        await admin
          .database()
          .ref(`/user_chat_messages/${senderUid}/${receiverUid}/${messageUid}`)
          .update({
            isSend: timestamp,
          })
    
        // sender chat
        await admin
          .database()
          .ref(`/user_chats/${senderUid}/${receiverUid}`)
          .update({
            unread: 0,
            displayName: receiverName,
            photoURL: receiverPhoto,
            lastMessage: lastMessage,
            authorUid: senderUid,
            lastCreated: created,
            isSend: timestamp,
            isRead: null,
          })
    
        // receiver chat
        await admin
          .database()
          .ref(`/user_chats/${receiverUid}/${senderUid}`)
          .update({
            displayName: senderName,
            photoURL: senderPhoto,
            authorUid: senderUid,
            lastMessage: lastMessage,
            lastCreated: created,
            isRead: null,
          })
    
        // update unread
        await admin
          .database()
          .ref(`/user_chats/${receiverUid}/${senderUid}/unread`)
          .transaction((number) => {
            return (number || 0) + 1
          })
    
        if (authorUid !== receiverUid) {
          const messages = []
    
          const payload = {
            notification: {
              title: `${snapValues.authorName}`,
              body: lastMessage,
            },
            webpush: {
              notification: {
                title: `${snapValues.authorName}`,
                body: lastMessage,
                icon: authorPhotoUrl ? authorPhotoUrl : '/apple-touch-icon.png',
                image,
                click_action: `https://www.react-most-wanted.com/chats/${senderUid}`,
              },
            },
            data: {
              test: 'test',
            },
          }
    
          const tokensSnap = await admin
            .database()
            .ref(`notification_tokens/${receiverUid}`)
            .once('value')
    
          if (tokensSnap.exists()) {
            tokensSnap.forEach((t) => {
              messages.push({ token: t.key, ...payload })
            })
          }
    
          await admin.messaging().sendAll(messages)
        }
      })
    

    【讨论】:

    • 这里的关键点(对于 OP,因为他们最初可能会忽略它)是 此代码运行在受信任的环境中,例如您的开发机器,您控制的服务器,或云函数。没有通过 Firebase 云消息传递直接从一个客户端向另一个客户端发送消息的安全方法。另见stackoverflow.com/questions/37990140/…
    • 啊,是的。我在写的时候就想到了这一点,忘了把它放进去:(
    猜你喜欢
    • 1970-01-01
    • 2021-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-22
    • 1970-01-01
    • 2016-12-08
    相关资源
    最近更新 更多