我做了一个firebase项目,我有2个Android应用程序连接到同一个数据库,让我们说第一个应用程序是一个“用户应用程序”,我正在分发给一些朋友,第二个是“管理员应用程序”(一个仅在我的个人电话上的应用程序)。 “用户应用程序”基本上只显示一些关于我所在城市事件的信息,而我使用“管理应用程序”从数据库中添加/删除这些事件
在我的用户应用程序中,我有一个非常标准的RecyclerView,使用FirebaseRecyclerAdapter显示一些卡片。单击一张卡片会弹出一个新的Activity,它会显示有关该事件的更多信息,使用Intent我将一个Id作为一个String传递,它会在数据库中加载相应的节点,一切正常。问题是,当我删除一个节点(来自Firebase控制台或amy“admin”应用程序)时,我的recyclerview中的“卡”仍然可用,点击它会导致NullPointerExeption,因为我正在寻找的对象显然不再在数据库中。
我在我的DatabaseReference上使用.keepSynced(true),我设置了setPersistanceEnabled,我认为这可能是问题所在。
我的适配器声明@OnStart看起来像这样:
if(recyclerView.getAdapter == null){
eventAdapter = new FirebaseRecyclerAdapter<DynamicData,EventViewHolder>
(
DynamicData.class,
R.layout.event_card,
EventViewHolder.class,
eventRef.orderByChild("eName")
){
@Override
protected void populateViewHolder(EventViewHolder viewHolder, DynamicData model, int position) {
final String post_key = getRef(position).getKey();
viewHolder.setDate(model.getDate());
viewHolder.setId(post_key);
viewHolder.setName(model.geteName());
viewHolder.setTime(model.getDate());
viewHolder.mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent toEvent = new Intent(getActivity(), EditEvent.class);
toEvent.putExtra("EVENT_ID",post_key);
startActivity(toEvent);
}
});
}
};
}
recyclerView.setAdapter(eventAdapter);
if(rcState != null){
recyclerView.getLayoutManager().onRestoreInstanceState(rcState);
}
所以这里真的没什么奇怪的。
我的OnSavedInstanceState:
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable(BUNDLE_RECYCLER_LAYOUT, linearLayoutManager.onSaveInstanceState());
rcState = outState.getParcelable(BUNDLE_RECYCLER_LAYOUT);
}
我使用OnStart togheter和onSavedInstanceState中的代码的if(recyclerView.getAdapter()== null)子句是唯一使我的Recycler视图滚动到正确位置的东西。没有这个代码,每当我用Intent更改活动时(通过点击recyclerView项目)然后返回,Recyclerview会重新创建并从顶部再次启动
重要:现在我正在打电话
@Override
public void onDestroy() {
super.onDestroy();
recyclerView.setAdapter(null);
eventAdapter.cleanup();
}
而不是onStop(),因为它显然是我在切换活动时保持我的recyclerView位置的唯一方法。
在我的“管理员应用程序”中,当我想从db中删除某些事件时,我使用此代码:
//Query fetching events older than 6 hours
Query returnsixHoursOldEvents =
eventRef.orderByChild("date").endAt(six_hours_cutoff);
returnsixHoursOldEvents.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot postSnapshot : dataSnapshot.getChildren()){
postSnapshot.getRef().removeValue();
}
}
现在的问题是,因为我从“管理员应用”中删除了这个事件,所以无法通过我的“用户应用”通知适配器。会发生的事情有时候(似乎是随机发生的)如果我的朋友打开他的应用程序,他仍然可以在他的recyclerview中看到我刚刚删除的事件,但如果他点击它,应用程序崩溃,因为数据库中的节点不再avaible
是keepSynced还是setPersistanceEnabled问题?任何解决方法?
答案 0 :(得分:1)
在共享数据模型中,很可能一个用户删除了另一个用户仍然看到的数据,特别是当其中一个用户暂时没有连接到Firebase时。您的代码必须处理这种情况。
像removeValue()
这样的方法不管数据是否存在:它们只是确保在它们执行后数据消失。