如何使用Firebase处理异步数据库? [英] How to handle asynchronous Database with Firebase?

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

问题描述

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

I have a lot of questions about handeling asynchronous database in my Android app.

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

Since I know that database is asynchronous, I've tried several things to handle it. As you can see in my code, I've two functions who need to use an array in my database. My first function (setArrayfromDatabase) will apply changes on my array in my database and my second function (setAnotherArray)need to use this array with changes applied from my first function. Here's my code :

    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的代码:

Here's the code for 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.addListenerForSingleValueEvent(new ValueEventListener()中包含 myReff.addValueEventListener(new ValueEventListener()的目的是如果我的数据库中的数组已被更改,则只执行onDataChange。但问题是情况并非如此。
这是首先打印的内容:1,3,3代替1,2,3,就像我期待的那样我的伎俩。

Here's my trick. The purpose of having an myReff.addValueEventListener(new ValueEventListener()inside another myReff.addListenerForSingleValueEvent(new ValueEventListener() is to only execute onDataChange if my array from database has been changed. But the problem is that it's not the case. Here's what's print first : 1, 3, 2 instead of 1, 2, 3 like I'm expecting with my trick.

你能帮助我吗?我是以错误的方式处理问题吗?我必须做的只是执行我的第二个函数,条件是我的数组有被更改了?在执行其他操作之前,如何让我的代码等待数据库中的更改?

希望您理解我,如果您对我的问题不理解,请随时问我问题。

Can you help me ? Am I handling the problem in the wrong way ? How must I do to only execute my second function, in condition that my array has been changed ? How can I keep my code waiting for changes in my database before executing something else ?
Hope you have understood me and feel free to ask me question if you doesn't understand something in my problem.

推荐答案

更改此:

   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){为此工作。

Some code may be missing from the above, but you get the idea add the code that is in the method public void setArray_for_database(ArrayList<Integer> array_from_database){ for this to work.

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

Since onDataChange is asynchronous meaning the program will keep executing, even if data is still not retrieved then this is the only way.

你获得1-3-的原因2,正因为如此:

The reason you get 1-3-2, is because of this:


  1. 它输入了第一个onDataChange

  2. 它打印了1

  3. 它输入了第一个内部的第二个onDataChange。

  4. 它打印3,因为它是异步的,然后检索数据时

  5. 它调用方法并打印2

  1. It entered the first onDataChange
  2. It printed "1"
  3. It entered the second onDataChange that is inside the first.
  4. It printed "3" since it is asynchronous, then when the data was retrieved
  5. It called the method and printed "2"

所以最好的方法是添加 onDataChange

So the best thing is to add the data in the method inside the onDataChange

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

The above will fix the asynchronous problem that you had in the question. But you really should denormalize your data.

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

Read this to learn more: https://firebase.googleblog.com/2013/04/denormalizing-your-data-is-normal.html

这篇关于如何使用Firebase处理异步数据库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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