【问题标题】:Retrieve String out of addValueEventListener Firebase从 addValueEventListener Firebase 中检索字符串
【发布时间】:2017-06-27 16:46:54
【问题描述】:

我想从addValueEventListener() 方法接收一个字符串,用于转售来自数据库 Firebase 的数据。数据正确到达。

但是当确定要从该方法中获取字符串以在另一个方法中使用它时,它什么也不返回。

你有什么建议吗?

我已经尝试过 putExtras 并且还故意创建了一个方法,但它不起作用。

final DatabaseReference mPostReference = FirebaseDatabase.getInstance().getReference().child("user-daily").child(getUid()).child("2017-Year");
mPostReference.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        final ArrayList<String> labels = new ArrayList<String>();
        for (DataSnapshot data : dataSnapshot.getChildren()){
            final DailyItem dailyItem = data.getValue(DailyItem.class);
            labels.add(dailyItem.mese);



        }
        title.setText(labels.get(position));

        a = title.getText().toString();
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        Toast.makeText(view.getContext(),"database error",
                Toast.LENGTH_SHORT).show();
    }
});

//this return null... why?
String title = a;

【问题讨论】:

    标签: android string firebase firebase-realtime-database


    【解决方案1】:

    数据是从 Firebase 异步加载的。当你运行title = a 时,onDataChange 方法还没有被调用。在调试器中设置一些断点来验证这一点,这是了解异步加载如何工作的关键。

    解决方案是将您的问题从“首先获取对象,然后对标题进行 blabla”重新构建为“开始获取对象;一旦对象可用,就使用标题进行 blabla”。

    在代码中,这转换为:

    final DatabaseReference mPostReference = FirebaseDatabase.getInstance().getReference().child("user-daily").child(getUid()).child("2017-Year");
    mPostReference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            final ArrayList<String> labels = new ArrayList<String>();
            for (DataSnapshot data : dataSnapshot.getChildren()){
                final DailyItem dailyItem = data.getValue(DailyItem.class);
                labels.add(dailyItem.mese);
    
    
    
            }
            title.setText(labels.get(position));
    
            // Do blabla with the title
            String title = title.getText().toString();
        }
    
        @Override
        public void onCancelled(DatabaseError databaseError) {
            Toast.makeText(view.getContext(),"database error",
                    Toast.LENGTH_SHORT).show();
        }
    });
    

    许多刚接触 Firebase(以及其他现代 Web API,因为它们都以这种方式工作)的开发人员都在为这个问题苦苦挣扎。所以我建议你也看看他们的问题和答案:

    【讨论】:

    • 感谢您的回复!但是,这并不能解决我的问题,因为我仍然无法带出这个字符串。我会看你留给我的申请。谢谢。
    • 您正在尝试使异步代码同步。见stackoverflow.com/questions/33203379/…
    • 谢谢了解!稍后我会在您给我的链接中查看答案,谢谢。最后一口井,只是猜测。如果我在来自 Firebase 的给定本地 proveninete 中除外,例如具有共享偏好,那么我将能够在方法之外检索它?
    • 这将允许在其他地方访问它,但是将title 声明为活动的字段也是如此。然而它不会改变你可以访问它:该值只有在onDataChange被触发之后才能访问。
    【解决方案2】:

    为了从 viewmodel 中的方法 addValueEventListener 或任何其他网络调用中检索字符串,建议使用 MutableLiveData&lt;T&gt;LiveData&lt;T&gt; 并在您的活动中观察相同的内容。观察者会观察变化,一旦字符串被填满,观察者方法会自动给你正在寻找的字符串。

    您需要为LiveData&lt;T&gt; reference_variable 创建引用变量,无论您的addValueEventLister 位于何处,并在您的addValueEventListener 中设置其值。

    然后在您的视图模型中创建返回值函数,如下所示... 在你的活动中观察这个函数,你就会得到你的字符串。

    public MutableLiveData<TotalRunsWicketsAndData> getDisplayableDetails() {
            return observableLiveData;
     }
    

    我在这里使用MutableLiveData

    【讨论】:

      【解决方案3】:

      这是一个技巧。如果要从 ValueEventListener 检索的数据较少,这样做会很容易。 在onDataChange() 中,使用 setText 在其中设置所需的值。将此文本视图的可见性保持为“已消失”。然后在 ValueEventListener 之外使用 getText 进行检索。

      【讨论】:

        【解决方案4】:

        您可以使用 GenericTypeIndicator 检索整个列表。关注here的官方指南

        【讨论】:

          猜你喜欢
          • 2023-03-05
          • 1970-01-01
          • 2017-10-10
          • 2012-02-13
          • 1970-01-01
          • 2021-11-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多