我正在尝试创建一个函数,该函数将发送有关文档是否已更新的通知。
我在更新文档时访问该文档,然后获取更新该文档的userId和所需的状态,此后,我只是查询用户设备令牌并发送有效负载,但似乎不起作用,我真的不知道代码的语法是否有错误或回调有问题。
const functions = require('firebase-functions');
var admin = require("firebase-admin");
{service keys are initialized here}
exports.onOrderCreated = functions.firestore
.document('orders/{orderId}').onUpdate(async (snap,context) => {
var db = admin.firestore();
try{
const orderDataSnap = await snap.ref.get();
var userId = orderDataSnap.data().uid;
var orderStatus = orderDataSnap.data().status;
}catch(error){
return handleErrorToUser(error,snap);
}
let docRef = db.collection('user').doc(userId);
return docRef.get().then(userDoc => {
const deviceToken = userDoc.get('deviceToken')
const payload = {
"data": {
"title": "Your order status here !",
"body": "Your order status is:"+orderStatus,
"icon": "ic_launcher",
"sound": "default",
"click_action": "delete_token"
}
}
return admin.messaging().sendToDevice(deviceToken,payload)
});
});
// Inform about errors (these errors are for testing purposes, we should use StackDriver to log the errors
// to ourselves and let a friendly user error message with this function)
async function handleErrorToUser(tError, snap) {
console.log(tError)
}
内部订单我必须获取这两个属性
用户名和状态
然后,使用该uid在用户引用中获取deviceToken。
这段代码给了我
TypeError: Cannot read property 'get' of undefined
> at exports.onOrderCreated.functions.firestore.document.onUpdate (/srv/index.js:17:46)
> at cloudFunction (/srv/node_modules/firebase-functions/lib/cloud-functions.js:131:23)
> at /worker/worker.js:825:24
> at <anonymous>
> at process._tickDomainCallback (internal/process/next_tick.js:229:7)
我对javascript没有太多经验,将不胜感激。
谢谢
答案 0 :(得分:2)
您在这里遇到了一些问题。
首先,onUpdate函数的第一个参数的名称可能不为snap
。如您在documentation for onUpdate中所见,第一个参数是一个Change对象,由于发生了更新,该对象包含针对文档的“之前”和“之后”状态的文档快照。该Change对象没有不具有名为ref
的属性,这将导致您的代码失败。
第二,如果您期望此代码获取已更新的文档:
const orderDataSnap = await snap.ref.get();
这里完全没有必要,因为文档的内容已经在我前面提到的Change对象中交付了。只需使用要提供的数据,除非您确定不能确定将要使用的数据即可。
我建议查看文档,以更好地了解更新触发器的工作原理。
答案 1 :(得分:1)
我认为问题出在这一行:
const deviceToken = userDoc.get('deviceToken')
如果'deviceToken'令牌是文档数据中的属性,则应首先运行data方法,该方法将返回所有文档数据属性:
const deviceToken = userDoc.data().deviceToken