[英]Chat message notification in Firebase Cloud Functions. Can't get data from a promise when triggering a Cloud Function
I develop in iOS and this is the first time I'm coding in Typescript. I made my first Cloud Function that triggers when a new chat message is sent in RTDB and notifies the members that receive the message.我在 iOS 开发,这是我第一次在 Typescript 编码。我制作了我的第一个 Cloud Function,它在 RTDB 中发送新聊天消息时触发并通知接收消息的成员。
When I make the call to Firestore to get tokens of the user devices (userTokens) I get no errors and have the correct path, but the data returned from those promises don't show anything.当我调用 Firestore 以获取用户设备的令牌 (userTokens) 时,我没有收到任何错误并且路径正确,但是从这些承诺返回的数据没有显示任何内容。 When I log the "tokenList" it just says ["0"].
当我记录“tokenList”时,它只是说 [“0”]。 I think the error is when I push the promise to a list or resolve them, but I haven't managed to fix it.
我认为错误是当我将 promise 推送到列表或解决它们时,但我还没有设法修复它。
The code:代码:
import * as functions from "firebase-functions"
import * as admin from "firebase-admin"
admin.initializeApp()
export const newLastMessageDetected = functions.database
.ref('/ChatMessages/{chatID}/{messageID}/')
.onCreate(async (snap, context) => {
const values = snap.val()
const chatID = context.params.chatID
const messageID = context.params.messageID
const message = values.message
const fromID = values.fromID
const fromName = values.fromName
console.log( `LastMessage changed with chatID: ${chatID} and messageID ${messageID} `)
console.log( `Last message: ${message} by fromID: ${fromID} and by name ${fromName}`)
const payload = {
notification: {
title: fromName,
body: message
}
}
let membersSnapshotRef = admin.database().ref('/Members/' + chatID + '/')
return membersSnapshotRef.once('value')
.then(dataSnapshot => {
const promises = []
console.log('*** GOT SNAPSHOT ***')
dataSnapshot.forEach((element) => {
if (element.key != fromID && element.val() === true) {
const p = admin.firestore().collection('userTokens').doc(`${element.key}`).collection('devices').get()
console.log('*** GOT PROMISE ***')
console.log(`*** The recipientID: ${element.key} ***`)
console.log(`${p}`)
promises.push(p)
}
})
return Promise.all(promises).then(snapshot => {
console.log('*** GOT RETURNED PROMISES ***')
const tokenList = []
const data = snapshot.keys()
for (const token in data) {
console.log(`${token}`)
tokenList.push(token)
}
console.log(`${tokenList}`)
return admin.messaging().sendToDevice(tokenList, payload).then(result => {
console.log("Notification sent!");
return null;
})
})
.catch(error => {
console.log(`${error}`)
})
})
})
When you use Promise.all()
, the result of the promise it returns is always going to be an array.当您使用
Promise.all()
时,它返回的 promise 的结果始终是一个数组。
Promise.all(promises).then(snapshot => {
// snapshot is an array of results with one element for each of the promises
})
You need to iterate that array to find the results of all the promises you stored in the promises
array.您需要迭代该数组以找到存储在
promises
数组中的所有 promise 的结果。 snapshot.keys()
does not iterate that array - it is just giving you a list of numbers that are the indexes of those array. snapshot.keys()
不会迭代该数组 - 它只是为您提供一个数字列表,这些数字是这些数组的索引。 Try using snapshot.forEach()
instead.尝试改用
snapshot.forEach()
。
You might want to review some documentation for promise.all .您可能想要查看promise.all 的一些文档。
I actually really messed up because I tried to retrieve the data on the query;我真的搞砸了,因为我试图检索查询中的数据; didn't realize that the first loop was on the retrieved queries, so I had to do another on the documents retrieved.
没有意识到第一个循环是针对检索到的查询,所以我不得不对检索到的文档执行另一个循环。 The device tokens are each of the documentIDs with the timestamp stored as the data.
设备令牌是每个文档 ID,其中时间戳存储为数据。
The working code:工作代码:
import * as functions from "firebase-functions"
import * as admin from "firebase-admin"
admin.initializeApp()
export const newLastMessageDetected = functions.database
.ref('/ChatMessages/{chatID}/{messageID}/')
.onCreate(async (snap, context) => {
const values = snap.val()
const chatID = context.params.chatID
const messageID = context.params.messageID
const message = values.message
const fromID = values.fromID
const fromName = values.fromName
console.log( `LastMessage changed with chatID: ${chatID} and messageID ${messageID} `)
console.log( `Last message: ${message} by fromID: ${fromID} and by name ${fromName}`)
const payload = {
notification: {
title: fromName,
body: message
}
}
let membersSnapshotRef = admin.database().ref('/Members/' + chatID + '/')
return membersSnapshotRef.once('value')
.then(dataSnapshot => {
const promises = []
// const docIDS = []
console.log('*** GOT SNAPSHOT ***')
dataSnapshot.forEach((element) => {
if (element.key != fromID && element.val() === true) {
const doc = admin.firestore().collection('userTokens').doc(`${element.key}`).collection('devices')
const p = doc.get()
// const docID = doc.id
console.log('*** GOT PROMISE ***')
console.log(`*** The recipientID: ${element.key} ***`)
// console.log(`*** The docID: ${docID} ***`)
promises.push(p)
// docIDS.push(docID)
}
})
return Promise.all(promises)
})
.then(async querySnapshot => {
console.log('*** GOT RETURNED PROMISES ***')
const tokenList = []
querySnapshot.forEach(snap => { // first here
console.log(`${snap.id} *** `)
console.log(`${snap} *** `)
snap.forEach(doc => { // then here
console.log(`${doc.id}`)
tokenList.push(doc.id)
})
})
await admin.messaging().sendToDevice(tokenList, payload)
console.log("Notification sent!")
return null
})
.catch(error => {
console.log(`${error}`)
})
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.