如何从onDataChange方法获取数据? [英] How can I get data out of onDataChange method?

查看:498
本文介绍了如何从onDataChange方法获取数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

情况:我想将函数参数中的 url 与从Firebase实时数据库中检索到的 url 进行比较.检索工作正常,但是,我不知道在if-else语句中如何从String比较中获取布尔值,在该错误中,我收到错误消息:无法为最终变量'bool'赋值"./p>

compare()代码:

private boolean compare(String url) {
    mDatabaseReference = mFirebaseDatabase.getReference("Executive Branch");
    final String newUrl = url;
    final boolean bool = false;

    mDatabaseReference.limitToFirst(1).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if (dataSnapshot.getChildrenCount() > 0) {
                for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                    ExecutiveOrder executiveOrder = snapshot.getValue(ExecutiveOrder.class);
                    if (executiveOrder.getUrl().equals(newUrl)) {
                        bool = true;
                    } else {
                        bool = false;
                    }
                }
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.e("Executive Order", "The read failed: " + databaseError.getDetails());
        }
    });

    return bool;
}

解决方案

您不能为最终变量分配新值.

如果要访问内部类中的外部类变量,则必须将它们声明为final.

一种简单但不优雅的方法是声明一个大小为1的布尔数组.

mDatabaseReference = mFirebaseDatabase.getReference("Executive Branch");
final String newUrl = url;
final boolean[] bool = new boolean[1];   //boolean array of size 1

mDatabaseReference.limitToFirst(1).addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        if (dataSnapshot.getChildrenCount() > 0) {
            for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                ExecutiveOrder executiveOrder = snapshot.getValue(ExecutiveOrder.class);
                if (executiveOrder.getUrl().equals(newUrl)) {
                    bool[0] = true;   //access the bool value like this
                } else {
                    bool[0] = false;
                }
            }
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        Log.e("Executive Order", "The read failed: " + databaseError.getDetails());
    }
});

顺便说一句,你犯了一个大错误.您的代码将一直返回false.

Firebase数据库方法是异步的,这意味着它们在单独的线程中执行,因此我们无法确定何时从数据库中检索它们的数据.这取决于您的互联网速度.

因此,您必须在onDataChange方法内调用适当的方法.例子...

private boolean compare(String url) {
    mDatabaseReference = mFirebaseDatabase.getReference("Executive Branch");
    final String newUrl = url;

    mDatabaseReference.limitToFirst(1).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if (dataSnapshot.getChildrenCount() > 0) {
                for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                    ExecutiveOrder executiveOrder = snapshot.getValue(ExecutiveOrder.class);
                    boolean bool = executiveOrder.getUrl().equals(newUrl);
                    doSomething(bool); //This method will handle the logic
                }
            }
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.e("Executive Order", "The read failed: " + databaseError.getDetails());
        }
    });
}

Situation: I want to compare a url from my function parameter with a url retrieved from my firebase realtime database. The retrieval works, however, I don't know how else to get a boolean value from the String comparison in my if-else statement, in which I get an error of: "Cannot assign value to final variable 'bool' ".

compare() code:

private boolean compare(String url) {
    mDatabaseReference = mFirebaseDatabase.getReference("Executive Branch");
    final String newUrl = url;
    final boolean bool = false;

    mDatabaseReference.limitToFirst(1).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if (dataSnapshot.getChildrenCount() > 0) {
                for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                    ExecutiveOrder executiveOrder = snapshot.getValue(ExecutiveOrder.class);
                    if (executiveOrder.getUrl().equals(newUrl)) {
                        bool = true;
                    } else {
                        bool = false;
                    }
                }
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.e("Executive Order", "The read failed: " + databaseError.getDetails());
        }
    });

    return bool;
}

解决方案

You cannot assign a final variable a new value.

And if you are gonna access outer class variables inside inner class they have to declared final.

One simple but not elegant way is to declare an boolean array of size 1.

mDatabaseReference = mFirebaseDatabase.getReference("Executive Branch");
final String newUrl = url;
final boolean[] bool = new boolean[1];   //boolean array of size 1

mDatabaseReference.limitToFirst(1).addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        if (dataSnapshot.getChildrenCount() > 0) {
            for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                ExecutiveOrder executiveOrder = snapshot.getValue(ExecutiveOrder.class);
                if (executiveOrder.getUrl().equals(newUrl)) {
                    bool[0] = true;   //access the bool value like this
                } else {
                    bool[0] = false;
                }
            }
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        Log.e("Executive Order", "The read failed: " + databaseError.getDetails());
    }
});

By the way you are making a big mistake. Your code is gonna return false all the time.

Firebase database methods are Asynchronous meaning they are executed in a separate thread so we cannot determent when they data will be retrieved from the database. It depends upon the speed of your internet.

So you have to call the appropriate method inside the onDataChange method. Example ...

private boolean compare(String url) {
    mDatabaseReference = mFirebaseDatabase.getReference("Executive Branch");
    final String newUrl = url;

    mDatabaseReference.limitToFirst(1).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if (dataSnapshot.getChildrenCount() > 0) {
                for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                    ExecutiveOrder executiveOrder = snapshot.getValue(ExecutiveOrder.class);
                    boolean bool = executiveOrder.getUrl().equals(newUrl);
                    doSomething(bool); //This method will handle the logic
                }
            }
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.e("Executive Order", "The read failed: " + databaseError.getDetails());
        }
    });
}

这篇关于如何从onDataChange方法获取数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆