当前位置: 首页 > 面试题库 >

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

岳君之
2023-03-14
问题内容

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

由于我知道数据库是异步的,因此我尝试了几种方法来处理它。如您在代码中所见,我有两个函数需要在数据库中使用数组。我的第一个函数(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、2而不是1、2、3,就像我期望的那样。

你能帮助我吗 ?我以错误的方式处理问题吗?在更改数组的情况下,我该怎么做才能仅执行第二个函数?在执行其他操作之前,如何使代码等待数据库中的更改?
希望您了解我,如果您对我的问题不了解,可以随时问我。


问题答案:

更改此:

   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”

因此,最好的方法是将数据添加到 onDataChange

上面的代码将解决您在问题中遇到的异步问题。但是您确实应该对数据进行非规范化。

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



 类似资料:
  • 我有一个简单的应用程序与一个共同的堆栈: 后端服务器(Rails) 前端应用程序(Vue) 数据库(PG) Vue应用程序使用Vuex存储库的操作从后端获取数据,如下所示: 在组件的已创建生命周期挂钩中调用该操作,如下所示: 我上面写的代码中有一个问题,我实际上在模板中使用了计算值“participation”,如下所示: 当然,因为我在组件呈现自身时使用了参与,所以我从getter方法中得到了这

  • 我试图弄清楚如何处理从返回的数据。 我有一个活动,我正在调用异步Firebase get操作(存在于其他类中的操作),并且我想使用检索到的ArrayList的大小更新活动中存在的。以下是我在活动创建中获取的 Firebase 调用: 这是我的Firebase操作: 在Android中,最好的方法是什么?是否有可能实现各种适配器或完成处理程序?

  • 问题内容: 现在,我有几次遇到使用Firebase的同步和异步功能的问题。我的问题通常是我需要在我编写的函数中进行异步Firebase调用。作为一个简单的示例,假设我需要计算并显示对象的速度,而我的Firebase存储距离和时间: 当然,上述代码将无法使用,因为它是异步调用,因此在到达时尚未设置。如果我们将内部放置在回调函数中,则什么也不会返回。 一种解决方案是使我的函数也异步。 另一种解决方案是

  • 问题内容: 我目前正在使用node.js应用程序,并且遇到了通常的异步代码问题。 我正在Node的HTTP模块之上实现服务服务器。 该服务器支持(类似表达)路由。例如,我有如下代码: 服务器需要能够承受故障,当传递给任何函数的问题出现时,我不想使整个服务器崩溃。当我编写如下代码时,会发生问题: 我看不到如何在这里捕获错误。我不想因一个服务器端故障而使服务器崩溃,而是要服务500个。 我能够提出的唯

  • 如果组件不是和路由绑定的页面组件,原则上是不可以使用异步数据的。因为 Nuxt.js 仅仅扩展增强了页面组件的 data 方法,使得其可以支持异步数据处理。 对于非页面组件,有两种方式可以实现数据的异步获取: 在组件的 mounted 方法里面实现异步获取数据的逻辑,之后设置组件的数据,限制是:不支持服务端渲染。 在页面组件的asyncData或fetch方法中进行API调用,并将数据作为prop

  • 在Servlet 3.0中,引入了异步处理的概念。所以所有的书都说这消除了每个请求一个线程的要求。我已经测试过了,是的,它确实有效。现在,我有一个简单的servlet,用户在其中以同步模式启动HTTP请求。线程只需Hibernate1秒,然后回复客户端。当我对这种模式进行负载测试时,服务器每秒只能处理4个请求。现在,我将同步模式更改为异步模式,并根据请求创建一个新线程,将原始http线程释放回池。