【问题标题】:android firebase get string from datasnapshot to the outsideandroid firebase从datasnapshot获取字符串到外部
【发布时间】:2017-10-09 11:51:45
【问题描述】:

假设我从 firebase 获取数据

    DatabaseReference mdb=FirebaseDatabase.getInstance().getReference("users/"+id);
        mdb.addValueEventListener(new ValueEventListener() {

            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                String name=dataSnapshot.child("name").getValue();
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }

        });

//point b

它运行良好.... 如果我尝试使用

打印该字符串名称
@Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                String name=dataSnapshot.child("name").getValue();
                System.out.println(name);
            }

它将打印该字符串。 但是如果我想在侦听器之外使用该字符串名称怎么办,例如在第一个代码中我添加了注释 //point b

我尝试在全局范围内定义字符串名称。 但它只打印 onDatachange() 内部的 println... 但它会在 //point b 打印 null ...即使我在全局范围内定义了字符串名称。

喜欢

String name;
    DatabaseReference mdb=FirebaseDatabase.getInstance().getReference("users/"+id);
        mdb.addValueEventListener(new ValueEventListener() {

            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                name=dataSnapshot.child("name").getValue();
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }

        });

//point b

编辑 实际上它是一个返回字符串值的函数,例如

public String getData(String id)
{
String name;
        DatabaseReference mdb=FirebaseDatabase.getInstance().getReference("users/"+id);
            mdb.addValueEventListener(new ValueEventListener() {

                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    name=dataSnapshot.child("name").getValue();
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {

                }

            });

return name;

}

【问题讨论】:

  • 它的打印 null 值因为 Firebase 监听器是异步的
  • 是什么意思?我不能在外面打印吗?
  • 您的打印代码在 firebase 监听器返回值之前执行
  • @Shruti 感谢您的指出,抱歉我刚刚改错了
  • 请指点我,我应该在哪里写println代码

标签: android firebase firebase-realtime-database


【解决方案1】:

数据是从 Firebase 异步加载的,不幸的是,这意味着您尝试的方法是不可能的

查看这一点的最简单方法是将代码简化为一些日志语句:

    DatabaseReference mdb=FirebaseDatabase.getInstance().getReference("users/"+id);
    System.out.println("Before attaching listener");
    mdb.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            System.out.println("Inside onDataChange");
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            throw databaseError.toException(); // Don't ignore errors
        }

    });
    System.out.println("After attaching listener");

当您运行此代码时,它会打印:

附加监听器之前

附加监听器后

onDataChange 内部

这可能不是您期望的输出,但完美地解释了为什么您无法从您的函数中返回 name:当您的 return 语句被执行时,尚未从 Firebase 加载数据。

没有办法等待数据可用。即使有,它也会导致您的应用程序被阻止并且 Android 显示臭名昭著的“应用程序无响应”对话框。

相反,您需要将需要访问名称的代码移动到 onDataChange 方法中,就像您在打印时所做的那样。

另见:

【讨论】:

    【解决方案2】:

    您无法访问 onDataChange 之外的变量。因此,如果您想访问函数/方法的变量,您可以在 onDataChange 中实现该方法。因为 onDataChange 将是最后一个运行的。因此,请确保在 onDataChange 中完成与变量相关的任何事情。

    【讨论】:

      猜你喜欢
      • 2018-01-19
      • 1970-01-01
      • 1970-01-01
      • 2011-05-31
      • 2012-12-12
      • 2019-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多