【问题标题】:How do I get Android client side callback to fire after Firebase Cloud Function onWrite finishes?Firebase Cloud Function onWrite 完成后,如何让 Android 客户端回调触发?
【发布时间】:2017-12-06 04:31:23
【问题描述】:

所以我在一个用户页面上,我想让用户创建一个帖子,但在服务器端进行扇出。

exports.fanoutUpdatePost = functions.database.ref('/post/{postKey}').onWrite(event => {
        var post = event.data.val();

        var fanoutObject = {};

        fanoutObject['/user-post/'+post.userKey+'/post/'+event.params.postKey] = post;
        fanoutObject['/blog-post/'+post.blogKey+'/post/'+event.params.postKey] = post;

       return event.data.adminRef.root.update(fanoutObject);
});

我这样做是为了让您可以在/post/ 上发帖,服务器将自动扇出。 问题是我希望客户端显示进度条,直到它保存在 /user-post/ 中。

但是在/post/ 上创建帖子后,我的客户端回调会立即触发。


public void addPost(final PostDao post, ProgressBar progressBar) {
    progressBar.setVisibility(View.VISIBLE);

    String key = mDatabase.child(“post”).push().getKey();

    Map<String, Object> postUpdateMap = new HashMap<>();
    postUpdateMap.put(“/post/” +key, post.toMap());

    mDatabase.updateChildren(postUpdateMap, new DatabaseReference.CompletionListener() {
                @Override
                public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
                    if(databaseError == null){
                        Log.e(TAG, databaseError);
                    }else{
                        // @@@@@ This executes before server side 
                        // @@@@@ cloud function fanoutUpdatePost 
                        // @@@@@ finishes. Can I make this happen 
                        // @@@@@ after it?
                    }
                }
            });
}

有没有办法等到我的 onWrite 云函数完成?

【问题讨论】:

    标签: java android firebase google-cloud-functions


    【解决方案1】:

    数据库写入不可能等待某些云功能完成。写入对云函数一无所知 - 写入只是成为函数在一段时间后消耗的事件。

    如果您需要等待云函数完成,将其编写为 HTTPS 触发器并直接从客户端调用它会更容易,只有在完成后才返回响应。在请求中发送要发布的数据,并让函数负责执行所有实际的数据库写入。

    【讨论】:

    • 我有点想避免这种情况,因为我也想使用数据库规则。这种方式与事物的“Firebase方式”太不同了。我想做服务器端扇出,尽管这有点麻烦,以尽量减少我早期应用程序的高度复杂/冗余的数据库规则。谢谢你的建议!
    【解决方案2】:

    对于您的特定用例,我推荐 Doug 的方法。

    但另一种选择是将您的数据库视为一堆请求/响应队列。因此,与其创建博文,不如说您正在编写创建该博文的请求。

    post-requests
      $pushid
        title: "..."
        body: "..."
    

    然后您的 Cloud Functions 代码处理此请求,编写实际的博客文章,写入扇出数据,删除请求,最后,将响应写回客户端:

    post-responses
      $pushid: "ok"
    

    这里的技巧是请求和响应使用相同的推送 ID。因此,一旦客户端推送了它的请求,它就知道它的响应最终会出现在哪里。

    现在从客户的角度来看,它:

    1. 将请求推送到数据库
    2. 开始监听响应队列中的响应
    3. 处理响应

    虽然这种方法在这里看起来很重要,但它对于较长的异步进程很有用,在这些进程中,您不能/不想在处理您的请求时在客户端和服务器之间保持单个 HTTP 请求处于打开状态。

    【讨论】:

    • 有趣,这就是我在发布问题之前设计解决方案的方式。我只是希望有一个更快的解决方案。我想构建一个内置的 firebase 解决方案有点尴尬,因为正如 Doug 所提到的,onWrite 只是接收写入事件并作为该写入事件/操作的简单订阅者执行。非常感谢!
    • 这里的缺点是如果客户端无法获取响应(因为它死了并且无法恢复之前的操作),很多响应将被收集到响应区域,如果您找不到清理它们的方法,随着时间的流逝,这将花费您的钱。
    • 我这里也讲一下这个方法:youtube.com/watch?v=eWj6dxfN63g&t=690s
    猜你喜欢
    • 2018-05-16
    • 2020-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-14
    相关资源
    最近更新 更多