如何使用Firebase处理异步数据库?

时间:2018-02-10 12:19:47

标签: java android firebase asynchronous firebase-realtime-database

我在Android应用程序中有很多关于handeling异步数据库的问题。

因为我知道数据库是异步的,所以我尝试了几件事来处理它。正如您在我的代码中看到的那样,我需要在数据库中使用数组的两个函数。我的第一个函数(setArrayfromDatabase)将在我的数据库中对我的数组应用更改,而我的第二个函数(setAnotherArray)需要使用此数组,并在第一个函数中应用更改。这是我的代码:

    FirebaseDatabase database = FirebaseDatabase.getInstance();
final DatabaseReference myReff =database.getReference("server").child("user");

    myReff.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {

        //Take the array from my database
        final ArrayList<Integer> array_from_database;
        GenericTypeIndicator<ArrayList<Integer>> genericTypeIndicator = new GenericTypeIndicator<ArrayList<Integer>>() {};
        array_from_database = dataSnapshot.getValue(genericTypeIndicator) ;

        System.out.println("1");

        //use this array in this first function, and this function will modify it.
        setArray_for_database(array_from_database);

        myReff.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                //this will be executed only if my array is changed (So only if my other function have been correctly executed
                setAnotherArray(array_from_database);
                System.out.println("3");
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {}
        });
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {

    }
});

这里是setArray_for_database:

的代码
    public void setArray_for_database(ArrayList<Integer> array_from_database){

    FirebaseDatabase database = FirebaseDatabase.getInstance();
    final DatabaseReference myReff =database.getReference();

    //Take the array from my database (gived in parameter)
    final ArrayList<Integer> array = array_from_database;

    myReff.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

            //this will be executed, even if data hasn't been changed because of the method (addListenerForSingleValueEvent)

            System.out.println("2");

            array.set(0,3);

            Map<String, Object> chemainChild = new HashMap<>();
            chemainChild.put("server/user/",array);

            myReff.updateChildren(chemainChild);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {}
    });
}

这是我的伎俩。在另一个myReff.addValueEventListener(new ValueEventListener()内部使用myReff.addListenerForSingleValueEvent(new ValueEventListener()的目的是仅在我的数据库中的数组已更改时才执行onDataChange。但问题是事实并非如此。 这是第一次打印的内容:1,3,3而不是1,2,3,就像我期待的一样。

你能帮帮我吗?我是以错误的方式处理问题吗?如果我的阵列已被更改,我该如何才能执行我的第二个功能?在执行其他操作之前,如何让代码等待数据库中的更改? 希望你了解我,如果你对我的问题不了解,请随时问我问题。

1 个答案:

答案 0 :(得分:1)

改变这个:

   myReff.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

            //this will be executed only if my array is changed (So only if my other function have been correctly executed
            setAnotherArray(array_from_database);
            System.out.println("3");
        }

到此:

final FirebaseDatabase database = FirebaseDatabase.getInstance();
final DatabaseReference myReff = database.getReference();

  myReff.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

          DatabaseReference ref2 = database.getReference();

          //Take the array from my database (gived in parameter)
          final ArrayList<Integer> array = array_from_database;
           System.out.println("2");

        array.set(0,3);

        Map<String, Object> chemainChild = new HashMap<>();
        chemainChild.put("server/user/",array);

        myReff.updateChildren(chemainChild);

            System.out.println("3");
        }

上面可能缺少某些代码,但您可以添加方法public void setArray_for_database(ArrayList<Integer> array_from_database){中的代码,以实现此目的。

由于onDataChange是异步的,意味着程序将继续执行,即使仍未检索到数据,这是唯一的方法。

你得到1-3-2的原因是因为:

  1. 它进入了第一个onDataChange
  2. 打印“1”
  3. 它进入了第一个内部的第二个onDataChange。
  4. 打印“3”,因为它是异步的,然后是检索数据时
  5. 调用方法并打印“2”
  6. 最好的办法是在onDataChange

    中的方法中添加数据

    以上将解决您在问题中遇到的异步问题。但你真的应该对数据进行非规范化。

    阅读本文以了解更多信息:https://firebase.googleblog.com/2013/04/denormalizing-your-data-is-normal.html