我是FireStore的新手。我创建了一个ListenerRegistration来更新我的Recycler View。我知道我的实现可能并不完美,但每次我的活动被破坏时,我的应用程序都会在此监听器内的行上引发错误。我不知道为什么,但mt registration.remove()在destroy之前或者finish()活动之后都没有工作。有人可以帮忙吗?
private ListenerRegistration registration;
private com.google.firebase.firestore.Query query;
private void requestPacienteList(){
FirebaseFirestore db = FirebaseFirestore.getInstance();
progress.setVisibility(View.VISIBLE);
query = db.collection("Hospital");
registration = query.addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {
for(DocumentSnapshot documentSnapshot : documentSnapshots){
if(documentSnapshot.get("nome").equals("Santa Clara")){
hospital = documentSnapshot.toObject(Hospital.class);
hospital.setHospitalDocumentKey(documentSnapshot.getId());
FirebaseFirestore db = FirebaseFirestore.getInstance();
db.collection("Hospital").document(hospital.getHospitalDocumentKey()).collection("Pacientes").addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {
homeModelList.clear();
for(DocumentSnapshot documentSnapshot : documentSnapshots){
final Paciente paciente = documentSnapshot.toObject(Paciente.class);
paciente.setPacienteKey(documentSnapshot.getId());
FirebaseFirestore db = FirebaseFirestore.getInstance();
db.collection("Pessoa").document(paciente.getProfissionalResponsavel()).addSnapshotListener(new EventListener<DocumentSnapshot>() {
@Override
public void onEvent(DocumentSnapshot documentSnapshot, FirebaseFirestoreException e) {
Profissional profissional = documentSnapshot.toObject(Profissional.class);
int[] covers = new int[]{
R.drawable.ic_person_black};
HomeModel p = new HomeModel(paciente.getNome()+" "+paciente.getSobrenome(),paciente.getBox(),paciente.getLeito(),
covers[0],profissional.getNome()+ " "+profissional.getSobrenome(),paciente.getPacienteKey());
homeModelList.add(p);
homeAdapter.notifyDataSetChanged();
prepareListaPacientes();
}
});
}
}
});
}
}
}
});
}
switch (id){
case R.id.logout:
if(FirebaseAuth.getInstance().getCurrentUser()!=null)
FirebaseAuth.getInstance().signOut();
Intent it = new Intent(HomeActivity.this, MainActivity.class);
startActivity(it);
if(registration!=null)
registration.remove();
finish();
drawerLayout.closeDrawers();
break;
}
我的onDestroy方法:
@Override
protected void onDestroy() {
super.onDestroy();
registration.remove();
}
如果我删除了这个:
if(FirebaseAuth.getInstance().getCurrentUser()!=null)
FirebaseAuth.getInstance().signOut();
我的问题消失了。但如果我不这样做,我会收到以下错误:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object com.google.firebase.firestore.DocumentSnapshot.toObject(java.lang.Class)' on a null object reference
at santauti.app.Activities.Home.HomeActivity$4$1$1.onEvent(HomeActivity.java:200)
at santauti.app.Activities.Home.HomeActivity$4$1$1.onEvent(HomeActivity.java:197)
at com.google.firebase.firestore.DocumentReference.zza(Unknown Source)
at com.google.firebase.firestore.zzd.onEvent(Unknown Source)
at com.google.android.gms.internal.zzejz.zza(Unknown Source)
at com.google.android.gms.internal.zzeka.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
答案 0 :(得分:13)
当您use addSnapshotListener
you attach a listener被要求进行任何更改时。显然,在活动被破坏之前你必须detach those listeners。另一种方法是add the activity
to your call to addSnapshotListener
:
db.collection("Pessoa").document(paciente.getProfissionalResponsavel())
.addSnapshotListener(MainActivity.this, new EventListener<DocumentSnapshot>() {
您需要更新MainActivity.this
以匹配您的代码。
通过传入活动,Firestore可以在活动停止时自动清理侦听器。
另一种替代方法是使用get()
来获取那些嵌套的文档,它只读取文档一次。因为它只读一次,所以没有听众清理。
答案 1 :(得分:3)
使用registration.remove();
停止收听更改
Query query = db.collection("cities");
ListenerRegistration registration = query.addSnapshotListener(
new EventListener<QuerySnapshot>() {
// ...
});
// ...
// Stop listening to changes
registration.remove();
详细了解此内容:https://firebase.google.com/docs/firestore/query-data/listen#detach_a_listener
答案 2 :(得分:1)
如果您正在使用MVVM架构,特别是ViewModel和LiveData架构类,那么通过addSnapshotListener()方法传递活动不是一个好主意。
您需要做的是从addSnapshotListener方法存储ListenerRegistration并手动删除LiveData类的onInactive()方法上的侦听器。
答案 3 :(得分:0)
@Override
public void onEvent(DocumentSnapshot documentSnapshot,
FirebaseFirestoreException e) {
if (e != null) {
Log.w(LOG_TAG, ":onEvent", e);
return;
}
}
@Override
protected void onStop() {
super.onStop();
if (registration!= null) {
registration.remove();
registration = null;
}
}
答案 4 :(得分:0)
如果您要从FirebaseDatabase启动和停止实时更新,则应使用ListenerRegistration注册和注销EventListners。
完整代码:
MyActivity extends AppCompatActivity implements EventListener<QuerySnapshot>{
private CollectionReference collectionRef; //<- You will get realtime updates on this
private ListenerRegistration registration;
public void registerListner(){
registration = collectionRef.addSnapshotListener(this);
}
public void unregisterListener(){
registration.remove(); //<-- This is the key
}
@Override
public void onEvent(@javax.annotation.Nullable QuerySnapshot queryDocumentSnapshots, @javax.annotation.Nullable FirebaseFirestoreException e) {
for(DocumentChange dc : queryDocumentSnapshots.getDocumentChanges()){
Log.d("Tag", dc.getType().toString()+" "+dc.getDocument().getData());
}
}
}