Firebase Function throws an error: returned undefined, expected Promise or value. How do I resolve this

Firebase Function throws an error: returned undefined, expected Promise or value. How do I resolve this

这是我的 .ts 文件,我正在使用 then 方法并使用 catch 块来处理最终 return 语句中的错误。这是一个 Firestore 触发的后台函数,基本上我在创建文档时做了 3 件事 1.将数据复制到Firestore中的另一个文档 2.发送FCM通知 3. 创建一个名为 "notificationObject" 的 JSON 对象并将其添加到 Firestore

中的另一个文档
import * as functions from 'firebase-functions'
const admin = require('firebase-admin')

//When client followes a user, a firestore .onCreate() background function is triggered to
//1.add follower to the followee's followers sub collection
//2.an FCM notification to sent to the users
//3.A Notification doc is added to Notification Sub Collection
export const addTheNewFollower = functions.region('asia-east2').firestore.document
  ('Users/{followerUserId}/following/{followeeUserId}').onCreate((data, context) => {

  //get follower and followee Uids for identification
  const followeeUid = context.params.followeeUserId
  //for identification and notification payload data (Intent Extras for client)
  const followerUid = context.params.followerUserId

  //Get Follower user details that needs to be duplicated to the Followee's following Sub Coll
  //And also added to the notification Payload data
  admin.firestore().collection('Users').doc(followerUid).get().then((doc:{ exists: any; data: () =>         
any }) => {

//Extracting this separately as this need not be copied to the Followers sub-collection
const followerImageUrl = doc.data().DOWNLOAD_URL

//This data will be copied to the followers sub collection
const followerData = {
  name:  doc.data().name,
  uid: followerUid,
  userName: doc.data().userName,
}


  //get the notification token of the followee to identify & send notification to his device
  admin.firestore().collection('Users').doc(followeeUid).collection('notificationToken')
    .doc('theNotificationToken').get().then((notificationTokenDoc:{ exists: any; data: () => any })     
=> {

  const followeeNotificationToken = notificationTokenDoc.data().notificationToken

  //Create the Notification Payload content
  const notificationPayload = {
    notification: {
  title: 'You have a new follower!',
  body: `${followerData.userName}`,
  clickAction: ".People.PersonProfileActivity",
  image: `${followerImageUrl}`
    },
    data: {
  ACTIVITY_NAME: "PersonProfileActivity",
  //The below field name to be same as the one used in the client
  PERSON_UID_INTENT_EXTRA: followerUid,
  PERSON_NAME_INTENT_EXTRA: followerData.name,
  PERSON_USERNAME_INTENT_EXTRA: followerData.userName,
  //If the app is in the foreground then this channel will be used to trigger a notification and this     
//channel has to
  //be created at the client else, this will fail
  CHANNEL_ID: "Follow Update ID"
}
  }

  //random 11 digital Notification Doc Id
  const randomNotificationDocId = (Math.random() * 100000000000).toString()

  const notificationObject = {
message:`${followerData.userName} started following you`,
receivedTime: Date.now(),
//This is needed for client to access this doc and update the wasClicked field
notificationDocId: randomNotificationDocId,
senderName: followerData.name,
senderUid: followerData.uid,
//this will be false by default, will turn true at client when clicked
wasClicked: false,
//this type has to be same as in the client
notificationChannelId: "Follow Updates",
intentToActivity: "PersonProfileActivity",
intentExtrasUid: followerData.uid,
intentExtrasName: followerData.name,
intentExtrasUserName: followerData.userName,
  }

//Add the follower to the followee sub-collection

 admin.firestore().collection('Users').doc(followeeUid).collection('followers').doc(followerUid)
.set(followerData)

//Add the notification doc to the user's notification sub collection
    admin.firestore().collection('Users').doc(followeeUid).collection('Notifications')
.doc(randomNotificationDocId).set(notificationObject)

//Send the notification to the user
return admin.messaging().sendToDevice(followeeNotificationToken,     
notificationPayload).then(function(response: any) {
  console.log("Successfully sent message:", response);
  })
  .catch(function(error: any) {
  console.log("Error sending message:", error);

      })

    })

  })
})

功能按预期完成,但我在 Firebase 控制台收到 "Function returned undefined, expected Promise or value"。谁能告诉我我做错了什么

试试这个:

Return Promise.all([
    admin.firestore().collection('Users').doc(followeeUid).collection('followers').doc(followerUid).set(followerData)
    admin.firestore().collection('Users').doc(followeeUid).collection('Notifications').doc(randomNotificationDocId).set(notificationObject)
    admin.messaging().sendToDevice(followeeNotificationToken, notificationPayload)
])

如果您想更新 Firestore 或实时数据库中的更多字段,请将它们放在这个 return Promise.all([ ... ]) 语句中。

好的,所以我在这个文件中总共有 5 个方法。我不得不使用 'then()' 方法链接其中的 2 个,并将底部的 3 个方法添加到名为 promises 的数组中,并使用 Promise.all(promises) 命令将它们作为 promise 返回。

这是我的最终代码

export const addTheNewFollower = functions.region('asia-east2').firestore.document
('Users/{followerUserId}/following/{followeeUserId}').onCreate((data, context) => {


//get follower and followee Uids for identification
const followeeUid = context.params.followeeUserId
//for identification and notification payload data (Intent Extras for client)
const followerUid = context.params.followerUserId

//Get Follower user details that needs to be duplicated to the Followee's following 
//Sub Coll
//And also added to the notification Payload data
return admin.firestore().collection('Users').doc(followerUid).get().then((doc:{ 
exists: any; data: () => any }) => {

//Extracting this separately as this need not be copied to the Followers sub-    
//collection
const followerImageUrl = doc.data().DOWNLOAD_URL

//This data will be copied to the followers sub collection
const followerData = {
  name:  doc.data().name,
  uid: followerUid,
  userName: doc.data().userName,
}


//get the notification token of the followee to identify & send notification to his 
//device
return admin.firestore().collection('Users').doc(followeeUid)
.collection('notificationToken')
.doc('theNotificationToken').get().then((notificationTokenDoc:{ exists: any; data: () 
=> any }) => {

  const followeeNotificationToken = notificationTokenDoc.data().notificationToken

//Create the Notification Payload content
const notificationPayload = {
notification: {
  title: 'You have a new follower!',
  body: `${followerData.userName}`,
  clickAction: ".People.PersonProfileActivity",
  image: `${followerImageUrl}`
},
data: {
  ACTIVITY_NAME: "PersonProfileActivity",
  //The below field name to be same as the one used in the client
  PERSON_UID_INTENT_EXTRA: followerUid,
  PERSON_NAME_INTENT_EXTRA: followerData.name,
  PERSON_USERNAME_INTENT_EXTRA: followerData.userName,
  //If the app is in the foreground then this channel will be used to trigger a 
notification and this channel has to
  //be created at the client else, this will fail
  CHANNEL_ID: "Follow Update ID"
}
}

//random 11 digital Notification Doc Id
const randomNotificationDocId = (Math.random() * 100000000000).toString()

const notificationObject = {
message:`${followerData.userName} started following you`,
receivedTime: Date.now(),
//This is needed for client to access this doc and update the wasClicked field
notificationDocId: randomNotificationDocId,
senderName: followerData.name,
senderUid: followerData.uid,
//this will be false by default, will turn true at client when clicked
wasClicked: false,
//this type has be same as in the client
notificationChannelId: "Follow Updates",
intentToActivity: "PersonProfileActivity",
intentExtrasUid: followerData.uid,
intentExtrasName: followerData.name,
intentExtrasUserName: followerData.userName,
}


const promises = []
  //Add the follower to the followee sub-collection
  const p = admin.firestore().collection('Users').doc(followeeUid)
.collection('followers').doc(followerUid).set(followerData)
  promises.push(p)
  //Add the notification doc to the user's notification sub collection
  const p1 = admin.firestore().collection('Users').doc(followeeUid)
.collection('Notifications').doc(randomNotificationDocId).set(notificationObject)
  promises.push(p1)
  //Send the notification to the user
  const p2 = admin.messaging().sendToDevice(followeeNotificationToken, 
notificationPayload)
  promises.push(p2)

  return Promise.all(promises)
})

})

})