【问题标题】:Firebase Cloud Function called from Android works but always gets null response从 Android 调用的 Firebase 云函数可以工作,但总是得到空响应
【发布时间】:2018-10-29 06:00:27
【问题描述】:

我正在尝试调用一个 Google Firebase 云函数,该函数仅使用事务来检查我的 Firestore 中是否存在某些内容,然后删除它和另一个文档。我在单击按钮时从 Android 调用该函数,它确实有效,条目被删除,但我在 Android 中得到的响应为空,而不是我试图发回的消息。

云功能:

//Takes in the uid of the user who sent the request and the user who received it,
// and deletes the request
exports.cancelFriendRequest = functions.https.onCall((data, context) => {
    //Grab the parameters
    const sender = data.sender;
    const recipient = data.recipient;

    //Ensure parameters are good
    if(sender === undefined || sender === "" || recipient === undefined || recipient === "") {
        return res.status(400).send("Invalid arguments.");
    }

    const db = admin.firestore();

    //Build document references to check that friend request exists
    let receivedFriendRequestDocRef = db.doc("users/"+recipient+"/receivedFriendRequests/"+sender);
    let sentFriendRequestDocRef = db.doc("users/"+sender+"/sentFriendRequests/"+recipient);

    db.runTransaction(transaction => {
        return transaction.getAll(receivedFriendRequestDocRef, sentFriendRequestDocRef).then(docs => {
            //Check that the friend request exists
            if(!docs[0].exists) {
                return Promise.reject(new Error("Friend request does not exist."));
            }

            //Delete friend requests
            transaction.delete(receivedFriendRequestDocRef);
            transaction.delete(sentFriendRequestDocRef);

            return Promise.resolve("Friend request deleted successfully.");
        });
    }).then(result => {
        //I've also tried return res.status(200).send("Success: " + result);
        //But that wasn't working so I thought I'd try this, which I saw in a Google sample git repo
        return "Success: " + result;
    }).catch(err => {
        return err.toString();
    });
});

Android云函数调用:

public static Task<String> cancelFriendRequest(String sender, String recipient) {
        FirebaseFunctions mFunctions = FirebaseFunctions.getInstance();

        //Create the arguments to the callable function
        Map<String, Object> data = new HashMap<>();
        data.put("sender", sender);
        data.put("recipient", recipient);

        return mFunctions
                .getHttpsCallable("cancelFriendRequest")
                .call(data)
                .continueWith(new Continuation<HttpsCallableResult, String>() {
                    @Override
                    public String then(@NonNull Task<HttpsCallableResult> task) throws Exception {
                        //This continuation runs on either success or failure, but if the task
                        // has failed then getResult() will throw an Exception which will be
                        // propagated down.
                        String result = (String) task.getResult().getData();
                        return result;
                    }
                });
    }

Android中调用云函数的函数:

private static void cancelFriendRequest(String uid) {
    String userId = FirebaseAuth.getInstance().getCurrentUser().getUid();
    CloudFunctions.cancelFriendRequest(userId, uid).addOnCompleteListener(new OnCompleteListener<String>() {
        @Override
        public void onComplete(@NonNull Task<String> task) {
            String result = task.getResult();
            Log.e("Result", "" + result);
            Snackbar.make(mRecyclerView, result, Snackbar.LENGTH_LONG).show();
        }
    });
}

我很乐意提供更多信息。我还发现调用该函数非常慢。如果我将它设置为 onRequest 并通过手动导航到 URL 来调用它,它的工作速度非常快,但是 onCall 和从 Android 调用非常缓慢。无论如何,这是另一个问题,谢谢!

编辑:此外,Snackbar 会弹出(空的,因为它返回 null),在文档实际从数据库中删除之前的 10-15 秒。

【问题讨论】:

    标签: android node.js firebase google-cloud-functions


    【解决方案1】:

    您错过了 main 函数(在云函数代码上)中的返回,因此函数在事务完成执行之前返回。来自documentation

    使用这些推荐的方法来管理您的生命周期 功能:

    解析执行异步处理的函数(也称为 作为“后台函数”)通过返回一个 JavaScript 承诺。

    尝试返回交易 (return db.runTransaction(transaction =&gt; {....});),它应该可以工作,如下所示:

    //Takes in the uid of the user who sent the request and the user who received it,
    // and deletes the request
    exports.cancelFriendRequest = functions.https.onCall((data, context) => {
        //Grab the parameters
        const sender = data.sender;
        const recipient = data.recipient;
    
        //Ensure parameters are good
        if(sender === undefined || sender === "" || recipient === undefined || recipient === "") {
            return res.status(400).send("Invalid arguments.");
        }
    
        const db = admin.firestore();
    
        //Build document references to check that friend request exists
        let receivedFriendRequestDocRef = db.doc("users/"+recipient+"/receivedFriendRequests/"+sender);
        let sentFriendRequestDocRef = db.doc("users/"+sender+"/sentFriendRequests/"+recipient);
    
       return db.runTransaction(transaction => {
            return transaction.getAll(receivedFriendRequestDocRef, sentFriendRequestDocRef).then(docs => {
                //Check that the friend request exists
                if(!docs[0].exists) {
                    return Promise.reject(new Error("Friend request does not exist."));
                }
    
                //Delete friend requests
                transaction.delete(receivedFriendRequestDocRef);
                transaction.delete(sentFriendRequestDocRef);
    
                return Promise.resolve("Friend request deleted successfully.");
            });
        }).then(result => {
            //I've also tried return res.status(200).send("Success: " + result);
            //But that wasn't working so I thought I'd try this, which I saw in a Google sample git repo
            return "Success: " + result;
        }).catch(err => {
            return err.toString();
        });
    });
    

    【讨论】:

    • 非常感谢!我一定是直接忘了把它放在那里,因为当我看到那是你的回应时,我可以发誓我已经把它退回了,但可惜我没有。再次感谢!
    猜你喜欢
    • 2013-10-03
    • 2019-01-18
    • 2017-08-09
    • 2019-04-18
    • 1970-01-01
    • 1970-01-01
    • 2020-05-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多