【问题标题】:Is there a way to save data from a firebase Realtime Database without getting a null variable? [duplicate]有没有办法在不获取空变量的情况下从 firebase 实时数据库中保存数据? [复制]
【发布时间】:2022-01-03 11:52:30
【问题描述】:

我有一个 Firebase 实时数据库,我想检索一些数据并将它们放入数组列表中。

ArrayList<Item> itemsArray;
List<Item> itemsList;

DatabaseReference shopRef;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_shop);

    itemsArray = new ArrayList<>();

    shopRef = FirebaseDatabase.getInstance().getReference();

    Query query = shopRef.child("shop");

    query.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                Item item = new Item();
                item.setLogo(snapshot.child("Logo").getValue().toString());
                item.setName(snapshot.child("Name").getValue().toString());
                item.setDescription(snapshot.child("Description").getValue().toString());
                itemsArray.add(item);  //itemsArray is full

            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {
        }
    });

    itemsList = itemsArray; // itemsArray is null
}

问题是在监听器之后,看起来很容易修复,但是我不明白为什么arraylist为null。

数据库正常工作

Item 类工作正常

【问题讨论】:

  • 数据从 Firebase(和大多数现代云 API)异步加载,因为从 Internet 获取数据需要时间。在加载数据时,您的主代码继续执行,因此您的 itemsList = itemsArray; 在任何 itemsArray.add(item) 执行之前运行。 --- 解决方案总是相同的:任何需要数据库数据的代码,必须在onDataChange 中,从那里调用,或者以其他方式同步。请参阅我链接的问题以了解更多信息和示例。
  • 如果你了解 Kotlin,这篇文章,How to read data from Firebase Realtime Database using get()? 会有所帮助。

标签: java firebase firebase-realtime-database arraylist


【解决方案1】:

当您向查询添加侦听器时,您不会立即将数据返回到数组列表中。你写的意思是:

  • 在实时数据库上进行查询,
  • 接收到数据更改事件时(或添加监听器时)调用onDataChanged(DataSnapshot)函数

所以你需要的是将来获取数据时的回调。

这意味着您不会立即获得数据:

itemsList = itemsArray; // itemsArray is null

改为:

class MyActivity extends AppCompatActivity {
   private final List<Item> itemsArrayList = new ArrayList<>();

   @Override

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_shop);
    
        shopRef = FirebaseDatabase.getInstance().getReference();
    
        Query query = shopRef.child("shop");
    
        query.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                List<Item> snapshotItems = new ArrayList<>();
                for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                    Item item = new Item();
                    item.setLogo(snapshot.child("Logo").getValue().toString());
                    item.setName(snapshot.child("Name").getValue().toString());
                    item.setDescription(snapshot.child("Description").getValue().toString());

                    snapshotItems.add(item);
                }
                // Calling this function will add the data back to the list
                MyActivity.this.onItemsObtained(snapshotItems);
            }
    
            @Override
            public void onCancelled(@NonNull DatabaseError error) {
            }
        });
    }

    public void onItemsObtained(List<Item> items) {
        itemsArrayList.clear(); // To remove old Data
        itemsArrayList.addAll(items);
        
        // Continue your own logic...
    }

}

【讨论】:

  • 谢谢,现在一切都清楚了,显然它奏效了
猜你喜欢
  • 1970-01-01
  • 2011-03-20
  • 2020-10-12
  • 2020-04-13
  • 1970-01-01
  • 2012-12-16
  • 1970-01-01
  • 2023-01-12
  • 1970-01-01
相关资源
最近更新 更多