我已将以下JavaScript部署到Firebase Cloud Function中,但是即使我知道在指定的路径下保存了令牌,我仍会不断出现以下错误。
这个想法是在将新消息写入数据库时触发向设备的通知,然后它获取注册令牌,然后将其用于尝试向用户发送通知。
错误:提供给sendToDevice()的注册令牌必须是非空字符串或非空数组。
JS函数:
exports.notifyNewMessage = functions.database.ref('/messages/{pushId}/{message}').onCreate((snap, context) => {
const message = snap.val();
const fromId = message['fromId'];
const toId = message['toId'];
const messageTxt = message ['message'];
const imageUrl = message ['imageUrl'];
return admin.database().ref('/fcmtokens/' + toId + '/registration-tokens').once('value').then((userTok) => {
const registrationTokens = userTok.val()
console.log(registrationTokens);
return admin.database().ref('/users' + fromId).once('value').then((userDoc) => {
const senderName = userDoc.firstName //get('firstName')
const notificationBody = (imageUrl === "") ? "You received a new image message." : messageTxt
//build media messages notification
const payload = {
notification: {
title: senderName + " sent you a message",
body: messageTxt
},
data: {
SENDER_NAME: senderName,
SENDER_ID: fromId
}//end data
}//end payload
//send message
return admin.messaging().sendToDevice(registrationTokens, payload).then( response => {
const stillRegisteredTokens = registrationTokens
response.results.forEach((result, index) => {
const error = result.error
if (error) {
const failedRegistrationToken = registrationTokens[index]
console.error('blah', failedRegistrationToken, error)
if (error.code === 'messaging/invalid-registration-token'
|| error.code === 'messaging/registration-token-not-registered') {
const failedIndex = stillRegisteredTokens.indexOf(failedRegistrationToken)
if (failedIndex > -1) {
stillRegisteredTokens.splice(failedIndex, 1)
}
}
}
})//end forEach
return admin.database().ref("fcmtokens/" + recipientId).update({
registrationTokens: stillRegisteredTokens
})//end update
})//end sendToDevice
})//end return-then
})//end return-then
});
这是我的fcmtokens
数据库结构节点:
"fcmtokens" : {
"dBQdpR7l1WT2utKVxdX2" : {
"registration-tokens" : {
"c4PSCAUAg5s:Yw95DyVxwElE88LwX7" : true
}
}
}
问题更新:
我上面函数的更新数据库部分是为所有活动令牌创建一个名为registrationTokens
的单独分支。我想改写并更新registration-tokens
下的当前令牌?
return admin.database().ref("fcmtokens/" + recipientId).update({
registrationTokens: stillRegisteredTokens
})//end update
该图片显示了正在创建的新registrationTokens
分支。
答案 0 :(得分:0)
给出您的数据结构,此代码:
admin.database().ref('/fcmtokens/' + toId + '/registration-tokens').once('value').then((userTok) => {
const registrationTokens = userTok.val()
registrationTokens
的领先优势:
{
"c4PSCAUAg5s:Yw95DyVxwElE88LwX7" : true
}
然后您通过以下方式致电sendToDevice
:
return admin.messaging().sendToDevice(registrationTokens, payload).then( response => {
但是,如果您查看reference documentation for `sendToDevice,它会显示:
注册令牌
字符串数组
向其发送消息的设备的注册令牌的数组。
很显然,您的registrationTokens
不是数组,而只是对象。
要将其转换为数组,请使用Object.keys()
:
const registrationTokens = Object.keys(userTok.val())