CloudFunctions:请求发送两次

时间:2019-08-10 11:22:32

标签: firebase google-cloud-firestore google-cloud-functions

我有一个问题,自从学习以来,我需要帮助。

我有一个扑扑的应用程序,可保存Firebase / Firestore数据,当用户请求友谊时,我将其添加到发件人和目标用户上,更改了sendTo和sendBy的ID。

我的问题是CloudFunctions可以很好地检测到来自不同用户的2个集合已被更改,并通知我2x(目标用户)。所以代码很好,但应该只通知一次/目标用户

我正在使用FCM发送本地通知。

exports.sendRequestNotification = functions.firestore
  .document('users/{userId}/requests/{requestId}')
  .onCreate((snap, context) => {

    const docReq = snap.data()
    /*console.log(docReq)*/

    const sentBy = docReq.sentBy
    const sentTo = docReq.sentTo
    const contentRequest = docReq.code

    if(contentRequest !== null){
        // Get push token user to (receive)
        admin
          .firestore()
          .collection('users')
          .where('userId', '==', sentTo)
          .get()
          .then(querySnapshot => {
            querySnapshot.forEach(userTo => {
              /*console.log(`Found request user to: ${userTo.data().userId}`)*/
              if (userTo.data().pushToken) {
                // Get info user from (sent)
                admin
                  .firestore()
                  .collection('users')
                  .where('userId', '==', sentBy)
                  .get()
                  .then(querySnapshot2 => {
                    querySnapshot2.forEach(userFrom => {
                      /*console.log(`Found request user from: ${userFrom.data().userId}`)*/
                      const payload = {
                        notification: {
                          title: `${userFrom.data().nickname}`,
                          body: contentRequest,
                          badge: '1',
                          sound: 'default'
                        }
                      }
                      // Let push to the target device
                      admin
                        .messaging()
                        .sendToDevice(userTo.data().pushToken, payload)
                        .then(response => {
                          /*console.log('Successfully sent request:', response)*/
                        })
                        .catch(error => {
                          console.log('Error sending request:', error)
                        })
                    })
                  })
              } else {
                console.log('User request or token not found')
              }
            })
          })
        return null
    }
  })

1 个答案:

答案 0 :(得分:0)

从代码中还不清楚为什么它会发送两次通知(因为您检查了before(function () { cy.exec('npm run db:reset') // This run only once before ALL the spec }) beforeEach(function () { cy.log('RUN BEFORE EACH TEST IN EACH SPEC') }) )。但是可以确定的是,您没有返回将在所有异步操作(userTo.data().userId !== sentByget())完成后解决的Promise。

我建议您观看官方视频系列(https://firebase.google.com/docs/functions/video-series/),该视频很好地解释了有关为后台函数返回Promise(尤其是标题为“ Learn JavaScript Promises”的知识)的这一点。

尤其是,您将在视频中看到,如果不返回Promise,则Cloud Function可能会在异步操作完成之前终止,从而可能导致结果不一致(不合逻辑)。

因此,您应该尝试使用以下经过修改的代码,该代码将返回promise链:

sendToDevice()