【问题标题】:Firebase Cloud Function Finished with status ''error''Firebase 云功能已完成,状态为“错误”
【发布时间】:2018-06-01 22:13:25
【问题描述】:

我正在编写我的第一个云函数,以便在新用户注册我的 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);

}

谢谢。

【问题讨论】:

    标签: javascript firebase firebase-realtime-database google-cloud-functions


    【解决方案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() 返回的承诺来实际获取数据库中的值。 token 将包含该承诺,而不是数据库的内容。

    你还必须返回一个承诺,当所有异步工作都在函数中完成时解决,而你目前没有这样做。

    【讨论】:

    • 好的,非常感谢。日志现在显示,但是有一个小问题,它也显示:Function returned undefined, expected Promise or value, 我该如何解决?
    • 我的回答涵盖了您代码中的所有问题,包括您刚才提到的问题。
    • 好的,我现在才读完。我还有一个疑问是,要使用函数向设备发送通知,我是否从客户端的 firebase 消息传递服务获取令牌并提供令牌的路径,就像我在上面所做的那样,或者铸造一个新的令牌服务器端并推送通知。请问哪种方法更好?
    • 您不能创建自己的消息令牌。它们必须来自客户端设备。
    • 我已编辑问题以帮助您解决我对令牌的困惑。请看一看。谢谢。
    猜你喜欢
    • 2021-10-22
    • 2019-05-15
    • 2017-08-26
    • 2020-05-11
    • 2019-12-04
    • 2017-09-24
    • 1970-01-01
    • 2020-02-25
    • 2016-10-06
    相关资源
    最近更新 更多