My project uses Firestore as the database. I am having a fragment which when opened requests a document from Firestore in its onCreate method. I have attached an OnCompleteListener to the .get() method so that when the document fetch is complete, it updates UI.
The issue is that sometimes the user, after opening the fragment, quickly moves on to another fragment before the onCompleteListener is triggered. Or in some cases, the same fragment is called twice and while the first instance of the fragment is destroyed, its onCompleteListener is still alive and triggers after the first instance of the Fragment is destroyed. In both these scenarios, I get an exception
Fatal Exception: java.lang.IllegalStateException: Fragment ProfileFragment{4ee762 (a8f7ae01-23be-4d47-b695-68e273b992bf)} not attached to a context.
at androidx.fragment.app.Fragment.requireContext(Fragment.java:774)
at androidx.fragment.app.Fragment.getResources(Fragment.java:838)
at androidx.fragment.app.Fragment.getString(Fragment.java:860)
at com.desivideshi.productinfo.ProfileFragment$18.onComplete(ProfileFragment.java:903)
at com.google.android.gms.tasks.zzj.run(com.google.android.gms:play-services-tasks@@17.1.0:4)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at com.google.android.gms.internal.tasks.zzb.dispatchMessage(com.google.android.gms:play-services-tasks@@17.1.0:6)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6898)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Here is my code snippet inside ProfileFragment's onCreate method
documentReference.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if (mContext != null){
if (task.isSuccessful() && task.getResult() != null && task.getResult().getData() != null) {
Map<String, Object> productsDoc = task.getResult().getData();
productsList = (List<Map<String, String>>) productsDoc.get(getString(R.string.fs_f_products_list));
if(productsList == null){
productsList = new ArrayList<>();
}
mMyProfileData.setMyProductsList(productsList);
}
} else {
Toast.makeText(mContext, "Failed to load products", Toast.LENGTH_SHORT).show();
}
createTabLayout();
profileTabLayout.selectTab(profileTabLayout.getTabAt(profileTabLayout.getSelectedTabPosition()));
progressLayoutProfileTab.setVisibility(View.GONE);
}
}
});
Is there a way to remove the callback to OnCompleteListener which I can place in the onDestry()
or onDetach()
method of the Fragment in order to avoid this exception?