所以我在一个用户页面上,我想让用户在服务器端创建一个帖子但是扇出。
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云功能完成?
答案 0 :(得分:5)
数据库写入无法等待某些云功能的完成。写入对云功能一无所知 - 写入只会成为函数稍后消耗的事件。
如果您需要等待云功能的完成,如果您将其作为HTTPS触发器编写并直接从客户端调用它,只有当它发出响应时才会更容易。做完了。将数据发送到请求中的post,并让函数负责执行所有实际的数据库写入。
答案 1 :(得分:3)
对于您的具体用例,我建议使用Doug的方法。
但另一种方法是将您的数据库视为一堆请求/响应队列。因此,不要创建博客文章,而是说您正在编写创建该帖子的请求。
post-requests
$pushid
title: "..."
body: "..."
然后你的Cloud Functions代码处理这个请求,编写实际的博客文章,写出散开的数据,删除请求,最后,将响应写回客户端:
post-responses
$pushid: "ok"
这里的技巧是请求和响应使用相同的推送ID。因此,一旦客户端推送了它的请求,它就会知道它的响应最终会显示在哪里。
现在从客户的角度来看,它:
虽然这种方法在这里看起来很重要,但它对于更长的异步流程非常有用,在这种流程中您无法在请求时保持客户端和服务器之间的单个HTTP请求保持打开状态正在处理中。