FirestoreRecyclerAdapter is throwing a null object error when the adapter.startListening() method runs in onStart() method in my Fragment.
My Firestore Database
The (Desserts, Starters) are SubCollections of Menu Collection which is fetched dynamically with for loop.
MenuFragment.java
public class MenuFragment extends Fragment implements View.OnClickListener {
private View view;
private FirebaseFirestore db;
private FirebaseAuth mAuth;
private FirebaseUser mCurrentUser;
private String Ruid,mItemName,mItemPrice,mItemIsActive,mItemSpecs;
private FloatingActionButton mCreateNewMenuBtn;
private DocumentReference mResMenuCategoryRef, mMenuItemRef;
private ArrayList<String> categoryList;
private FirestoreRecyclerAdapter<MenuItemModel, MenuItemHolder> adapter;
LinearLayoutManager linearLayoutManager;
private RecyclerView mMenuItemRecyclerView;
public MenuFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(@NotNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_menu,container,false);
init();
getMenuItems();
mCreateNewMenuBtn.setOnClickListener(this);
return view;
}
private void init() {
mCreateNewMenuBtn = view.findViewById(R.id.createNewMenuBtn);
mAuth = FirebaseAuth.getInstance();
mCurrentUser = mAuth.getCurrentUser();
assert mCurrentUser != null;
Ruid = mCurrentUser.getUid();
db = FirebaseFirestore.getInstance();
mResMenuCategoryRef = db.collection("RestaurantList").document(Ruid);
mMenuItemRecyclerView = view.findViewById(R.id.menuItemRecyclerView);
linearLayoutManager = new LinearLayoutManager(requireActivity(), LinearLayoutManager.VERTICAL, false);
mMenuItemRecyclerView.setLayoutManager(linearLayoutManager);
}
private void getMenuItems() {
mResMenuCategoryRef.get().addOnCompleteListener(task -> {
if (task.isSuccessful()){
DocumentSnapshot documentSnapshot = task.getResult();
assert documentSnapshot != null;
if (documentSnapshot.exists()){
categoryList = (ArrayList<String>) documentSnapshot.get("Categories");
assert categoryList != null;
Log.d("CATEGORIES", categoryList.toString());
for(int i = 0 ; i < categoryList.size() ; i++){
String MenuItemSubCollection = categoryList.get(i);
CollectionReference menuItemReference = db.collection("Menu").document(Ruid).collection(MenuItemSubCollection);
menuItemReference.get().addOnCompleteListener(task1 -> {
if (task1.isSuccessful()){
for (QueryDocumentSnapshot document : Objects.requireNonNull(task1.getResult())) {
DocumentReference mMenuItemRef = menuItemReference.document(document.getId());
mMenuItemRef.get().addOnCompleteListener(task2 -> {
if (task2.isSuccessful()){
DocumentSnapshot mMenuItemSnapShot = task2.getResult();
assert mMenuItemSnapShot != null;
Query query = db.collection("Menu").document(Ruid).collection(MenuItemSubCollection);
FirestoreRecyclerOptions<MenuItemModel> menuItemModel = new FirestoreRecyclerOptions.Builder<MenuItemModel>()
.setQuery(query, MenuItemModel.class)
.build();
adapter = new FirestoreRecyclerAdapter<MenuItemModel, MenuItemHolder>(menuItemModel) {
@Override
public void onBindViewHolder(MenuItemHolder holder, int position, MenuItemModel model) {
holder.mItemName.setText(model.getName());
Log.d("SHOWING", model.getName());
String specImage = model.getSpecification();
if (specImage.equals("Veg")){
Glide.with(Objects.requireNonNull(requireActivity()))
.load(R.drawable.veg_symbol).into(holder.foodSpecification);
}else {
Glide.with(Objects.requireNonNull(requireActivity()))
.load(R.drawable.non_veg_symbol).into(holder.foodSpecification);
}
holder.mItemPrice.setText(model.getPrice());
holder.itemView.setOnClickListener(v -> {
});
}
@Override
public MenuItemHolder onCreateViewHolder(ViewGroup group, int i) {
View view = LayoutInflater.from(group.getContext())
.inflate(R.layout.menu_item_details, group, false);
return new MenuItemHolder(view);
}
@Override
public void onError(FirebaseFirestoreException e) {
Log.e("error", e.getMessage());
}
};
adapter.notifyDataSetChanged();
mMenuItemRecyclerView.setAdapter(adapter);
}
});
}
}
});
}
}
}
});
}
public class MenuItemHolder extends RecyclerView.ViewHolder {
@BindView(R.id.itemName)
TextView mItemName;
@BindView(R.id.foodMark)
ImageView foodSpecification;
@BindView(R.id.itemPrice)
TextView mItemPrice;
@BindView(R.id.itemActiveSwitch)
Switch isActiveSwitch;
public MenuItemHolder(View itemView) {
super(itemView);
ButterKnife.bind(requireActivity(), itemView);
}
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.createNewMenuBtn:
Fragment fragment = new CreateNewMenuFragment();
FragmentManager fragmentManager = Objects.requireNonNull(getActivity()).getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragmentContainer, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
break;
}
}
@Override
public void onStart() {
super.onStart();
adapter.startListening();
}
@Override
public void onStop() {
super.onStop();
adapter.stopListening();
}
}
MenuItemModel.java
public class MenuItemModel {
private String name;
private String price;
private String specification;
public MenuItemModel(String name, String price, String specification) {
this.name = name;
this.price = price;
this.specification = specification;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getSpecification() {
return specification;
}
public void setSpecification(String specification) {
this.specification = specification;
}
}
LogCat
2020-07-09 20:47:57.251 1689-1689/com.example.muncherestaurantpartner E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.muncherestaurantpartner, PID: 1689
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.firebase.ui.firestore.FirestoreRecyclerAdapter.startListening()' on a null object reference
at Fragments.MenuFragment.onStart(MenuFragment.java:205)
at androidx.fragment.app.Fragment.performStart(Fragment.java:2632)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:915)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
at androidx.fragment.app.FragmentManagerImpl$2.run(FragmentManagerImpl.java:150)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:201)
at android.app.ActivityThread.main(ActivityThread.java:6864)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)