首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >安卓:等待firebase valueEventListener

安卓:等待firebase valueEventListener
EN

Stack Overflow用户
提问于 2016-08-16 11:08:34
回答 2查看 9K关注 0票数 6

我正在尝试使用信号量来等待我的firebase valueEventListener。我有一个用户信息活动与6个不同的领域,用户必须填写。当用户保存他/她的信息时,我想做一个“全有或全无”类型的检查。某些用户信息不能是duplicated...for例如用户名、电子邮件和电话号码。我使用的是firebase,目前的总体思路是:

代码语言:javascript
运行
复制
void saveUserInfo(){
    if(field1 exist in database){
        return;
    }
    .
    .
    .
    if(field6 exist in database){
        return;
    }

    savefield1();
    .
    .
    .
    savefield6();
}

我遇到的问题是检查数据库中是否已经存在该值的方法。下面是我当前的方法:

代码语言:javascript
运行
复制
   public boolean alreadyInUse(String key, String value) throws InterruptedException {

    final StringBuilder done = new StringBuilder("");
    final Semaphore semaphore = new Semaphore(0);

    mDatabase.child(key).child(value).addListenerForSingleValueEvent(new ValueEventListener() {

        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            String result = dataSnapshot.getValue(String.class);
            if(result == null){
                Log.d("WorkoutLog", "result: null");
                done.append("false");
                semaphore.release();
                return;
            }
            else if(result.equals(uID)){
                Log.d("WorkoutLog", "result: " + result.toString());
                done.append("false");
                semaphore.release();
                return;
            }
            else{
                Log.d("WorkoutLog", "result: " + result.toString());
                done.append("true");
                semaphore.release();
                return;
            }

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });


    semaphore.acquire();
    if(done.equals("true")){
        return  true;
    }
    else if(done.equals("false")){
        return false;
    }
    else{
        Log.d("WorkoutLog", "Shouldn't be here");
        return true;
    }

}

现在信号量不是releasing...Was,不知道有没有人能帮我。如果没有信号量,则返回语句将在firebase查询完成之前触发...

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-16 11:46:42

侦听器回调方法在主线程上运行。如果在主线程上调用alreadyInUse(),它将阻塞semaphore.acquire()处的线程,阻止回调运行并释放信号量。

您可能会发现相关问题的this answer很有帮助。

票数 7
EN

Stack Overflow用户

发布于 2016-11-15 01:35:07

如前所述,您可以使用Google I/O 2016上提供的Firebase Task API

代码语言:javascript
运行
复制
Task<?>[] tasks = new Task[] {
    saveUserName(username),
    saveFriends(friends),
    saveOtherStuff(stuff)
};

Tasks.whenAll(tasks)
    .continueWithTask(new RollbackIfFailure())
    .addOnCompleteListener(this)
    .addOnFailureListener(this);

如果进行修改的每个步骤都可以并行运行,则可以创建一个方法,为每个步骤返回一个Task,如下所示:

代码语言:javascript
运行
复制
public Task<String> saveUserName(final String username) {
    final TaskCompletionSource<String> tcs = new TaskCompletionSource<>();

    mDatabase.child("users")
        .child(username)
        .addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            String username = dataSnapshot.getValue(String.class);
            if (null == username) {
                tcs.setResult(null);
            } else {
                tcs.setException(new IllegalStateException(username));
            }
        }

        @Override
        public void onCancelled(FirebaseError firebaseError) {
            tcs.setException(new IOException(TAG, firebaseError.toException()));
        }
    });

    return tcs.getTask();
}

如果其中任何一个失败,您需要回滚操作。由于这可能会受到单个任务的威胁,因此您可以创建一个Continuation任务:

代码语言:javascript
运行
复制
class RollbackIfFailure implements Continuation<Void, Task<Void>> {
    @Override
    public Task<Void> then(@NonNull Task<Void> task) throws Exception {

        final TaskCompletionSource<Void> tcs = new TaskCompletionSource<>();

        if (task.isSuccessful()) {
            tcs.setResult(null);
        } else {
            // Rollback everything
        }

        return tcs.getTask();
    }
}
票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38966056

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档