【问题标题】:How to retrieve data from firebase database without listening for events [duplicate]如何在不监听事件的情况下从 firebase 数据库中检索数据 [重复]
【发布时间】:2018-09-08 00:58:52
【问题描述】:

您好,我正在为我的 android 应用程序使用 Firebase 数据库。我将数据存储在 firebase 数据库中,我想在创建片段时获取它,但是当我启动我的应用程序时,方法(从 firebase 数据库获取数据)返回空值 每当我使用 android 设备恢复片段时,recyclerView 都会填充来自 firebase 的数据。 我的问题是为什么列表第一次返回 null。以及如何在创建片段时获取数据

OffersFragment

 @Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View offersView = inflater.inflate(R.layout.fragment_offers, container, false);

    mOffersRecyclerView = offersView.findViewById(R.id.rv_offers);
    mAddCard = offersView.findViewById(R.id.fab_add_card);

    setUp();

    return offersView;
}

@Override
public void setPresenter(OffersContract.Presenter presenter) {
    mPresenter = presenter;
}

@Override
public void setUp() {
    mOffersList = mPresenter.getOffersList();
    mOffersAdapter = new OffersAdapter(getActivity(), mOffersList);

    mOffersRecyclerView.setAdapter(mOffersAdapter);
    RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
    mOffersRecyclerView.setLayoutManager(layoutManager);
    mOffersRecyclerView.setHasFixedSize(false);

    performActions(mAddCard);
}

OffersPresenter

 @Override
public List<Offers> getOffersList() {

    return databaseHelper.getOffers();
}

DatabaseHelper -> getOffers()

public List<Offers> getOffers() {
    DatabaseReference offerReference = getDatabase().child("offers");

    offerReference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            final Iterable<DataSnapshot> children = dataSnapshot.getChildren();

            for (DataSnapshot d : children) {
                offersList.add(d.getValue(Offers.class));
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
    return offersList;
}

【问题讨论】:

  • 请检查副本以了解发生这种情况的确切原因。

标签: android firebase android-fragments firebase-realtime-database android-mvp


【解决方案1】:

firebase 回调是异步的,因此 getOffers 方法将在回调更新之前返回 null。 您必须将适配器实例和列表实例传递给 firebase 回调,以便它从那里更新 试试这个机制: 在您的活动中初始化您的列表

@Override
public void setUp() {
    mOffersList = new ArrayList<Offers> ();
    mOffersAdapter = new OffersAdapter(getActivity(), mOffersList);

    mOffersRecyclerView.setAdapter(mOffersAdapter);
    RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
    mOffersRecyclerView.setLayoutManager(layoutManager);
    mOffersRecyclerView.setHasFixedSize(false);

    performActions(mAddCard);
}

更新你的吸气剂

@Override
public void getOffersList(List<Offers> offers, OffersAdapter adapter) {

    return databaseHelper.getOffers(offers, adapter);
}

助手会是这样的:

public void getOffers(List<Offers> offers,OffersAdapter adapter) {
    if (offers == null) offers = new ArrayList<Offers> ();
    DatabaseReference offerReference = getDatabase().child("offers");

    offerReference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            final Iterable<DataSnapshot> children = dataSnapshot.getChildren();

            for (DataSnapshot d : children) {
                offers.add(d.getValue(Offers.class));
            }
            adapter.notifyDataSetChanged();
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
}

请记住,您正在使用 value 事件,如果任何数据发生更改,该事件将被调用,因此数据将被多次添加。如果您有任何问题,请使用单值事件或子事件侦听器来解决问题。

【讨论】:

  • 好的@UmarHussain,但我所做的是,我没有将适配器和列表传递给 getOfferts(),而是将 View 从演示者类传递给 DatabaseHelper -> getOffers 并在那里我调用了 setUp()视图,我在片段的 onCreate 中调用 getOffersList。这是一个好的解决方案还是我应该使用上面的?。
  • 这也可以,但最后您必须将适配器实例传递给 firebase 回调以更新数据。
  • 我不这么认为,因为 Firebase 提供了实时数据库功能,因此只要将新数据添加到列表适配器中,数据就会立即更新
【解决方案2】:

它返回 null 因为您将 return offersList; 放在 public List&lt;Offers&gt; getOffers() 的末尾删除 return 语句并制作 getOffers() void 并添加逻辑以获取/更新您的数据和/或 commit() 您的片段在onDataChange(DataSnapshot dataSnapshot) 内部,所以它会在第一次获取数据时返回您的列表。

我通常做的是提交片段或将其参数设置在 onDataChange(DataSnapshot dataSnapshot)

【讨论】:

    猜你喜欢
    • 2018-02-12
    • 1970-01-01
    • 2020-07-09
    • 1970-01-01
    • 2018-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多