我正在编写我的第一个云功能,当新用户使用我的Android应用程序注册时发送推送通知。我已经完成了安装Node和firebase cli等基础知识并初始化了我的项目。
我在下面编写了这个测试函数来记录任何用户的用户ID以及他们的注册并部署到firebase的令牌。
exports.sendSignUpNotification =functions.database.ref('/users/{userId}').onWrite((change, context) => {
const user_id = context.params.userId;
//const notifID = context.params.notification_id;
console.log("User id at signup:\t", user_id);
//console.log("Notification id at signup:\t", notifID);
let token = admin.database().ref(`/users/{userId}/id_token`).once('value');
console.log("User id token:\t", token);
return new Promise().then(data => {
const payLoad = {
notification: {
title: "Thank You For Signing Up",
body: "Enjoy the best features by becoming a premium user"
}
};
return admin.messaging().sendToDevice(token, payLoad);
}).catch(errs => {
console.error("Error Sending Payload", errs);
});
});
这是完整功能的编辑代码,但不知怎的,我知道我在发送有效载荷时做错了。这是我在下面的错误:
TypeError: Promise resolver undefined is not a function
at exports.sendSignUpNotification.functions.database.ref.onWrite (/user_code/index.js:15:10)
at Object.<anonymous> (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:112:27)
at next (native)
at /user_code/node_modules/firebase-functions/lib/cloud-functions.js:28:71
at __awaiter (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:24:12)
at cloudFunction (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:82:36)
at /var/tmp/worker/worker.js:716:24
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
要在客户端获取令牌,我已在注册时调用此方法:
mAuth.getCurrentUser().getIdToken(true).addOnCompleteListener(new OnCompleteListener<GetTokenResult>() {
@Override
public void onComplete(@NonNull Task<GetTokenResult> task) {
if (task.isSuccessful()) {
String idToken = task.getResult().getToken();
Log.d(TAG, "idToken:\t" + idToken);
HashMap<String, String> usersMap = new HashMap<>();
usersMap.put("name", name);
usersMap.put("userId", userId);
usersMap.put("email", email);
usersMap.put("id_token", idToken);
}
我保存了此令牌并在我的脚本中引用了云功能。这是正确的令牌还是我应该使用FirebaseInstanceIdService
中的那个,如下所示:
@Override
public void onTokenRefresh() {
super.onTokenRefresh();
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed Token:\t" + refreshedToken);
}
谢谢。
答案 0 :(得分:1)
您正在使用旧的Beta版API和新的1.x版SDK。数据库事件的工作方式已更改。整个SDK的更改已汇总here。 onWrite事件现在有两个参数,一个是变更和一个上下文。更改包含前后快照,上下文包含通配符值。
要获取userId通配符,您现在可以说:
exports.sendSignUpNotification = functions.database.ref(`/users/{userId}`).onWrite((change, context) => {
const userId = context.params.userId
有关更多最新示例,请参阅documentation。
同样在你的代码中,这一行有一个错误:
let token = admin.database().ref(`/users/{userId}/notificationTokens`).once('value');
反引号分隔字符串中的变量插值的JavaScript语法需要美元符号:
`/users/${userId}/notificationTokens`
该行还有另一个错误。您没有使用once()返回的promise来实际获取数据库中的值。 token
将包含该承诺,而不是数据库的内容。
当你在函数中完成所有异步工作时,你还必须返回一个解决的承诺,你当前没有这样做。