I am designing a simple store/retrieve data android app using firebase.
Activity1
is a login activity, that goes straight to Activity2
when a user successfully logs in. There are no problems when logging in the first time, everything is in its proper place. I have a Navigation Drawer in Activity2
which I use to switch fragments, and in that navigation drawer, users can logout and go back to the login activity. Below is an excerpt from Activity2
that takes the user back to the login activity
case R.id.nav_logout:
account_key = "";
Toast.makeText(getApplicationContext(), "Logged Out", Toast.LENGTH_LONG).show();
Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
startActivity(intent);
finish();
break;
When I click the logout button, it takes me to Activity1
as it should be. Now the problem is when I try to login again, the app just crashes with the following error:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.adzu.bfarsystem, PID: 2143
java.lang.NullPointerException: Attempt to invoke interface method 'android.view.MenuItem android.view.Menu.add(int, int, int, java.lang.CharSequence)' on a null object reference
at android.view.MenuInflater$MenuState.addItem(MenuInflater.java:540)
at android.view.MenuInflater.parseMenu(MenuInflater.java:193)
at android.view.MenuInflater.inflate(MenuInflater.java:114)
at androidx.appcompat.view.SupportMenuInflater.inflate(SupportMenuInflater.java:120)
at com.adzu.bfarmobile.activities.MainActivity.createSearchView(MainActivity.java:153)
at com.adzu.bfarmobile.activities.MainActivity$1.dataRetrieved(MainActivity.java:109)
at com.adzu.bfarmobile.entities.DatabaseReader$3.onChildAdded(DatabaseReader.java:64)
at com.google.firebase.database.core.ChildEventRegistration.fireEvent(ChildEventRegistration.java:79)
at com.google.firebase.database.core.view.DataEvent.fire(DataEvent.java:63)
at com.google.firebase.database.core.view.EventRaiser$1.run(EventRaiser.java:55)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
And here are the lines that triggered the errors:
LoginActivity.java Lines 95-102
if (activated) {
Toast.makeText(getApplicationContext(), "Login Success!", Toast.LENGTH_LONG).show();
Intent newIntent = new Intent(getApplicationContext(), MainActivity.class);
newIntent.putExtra("account_key", dataSnapshot.getKey());
startActivity(newIntent);
finish();
}
MainActivity.java Line 95-127
Intent intent = getIntent();
account_key = intent.getStringExtra("account_key");
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("account");
DatabaseReader.readDataByKey(account_key, ref, new OnGetDataListener() {
@Override
public void dataRetrieved(DataSnapshot dataSnapshot) {
Account user = new Account((Map<String, Object>) dataSnapshot.getValue());
fragment1 = new ListFragment();
fragment1.setUser(user);
createSearchView();
showSearchView();
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, fragment1).commit();
navigationView.setCheckedItem(R.id.nav_operatorlist);
TextView acct_name = findViewById(R.id.acct_name);
acct_name.setText("Logged in as: " + user.getUsername());
}
@Override
public void dataExists(DataSnapshot dataSnapshot) {
}
@Override
public void onStart() {
}
@Override
public void onFailure() {
}
});
MainActivity.java Line 141-153
@Override
public boolean onCreateOptionsMenu(Menu menu) {
this.menu = menu;
return super.onCreateOptionsMenu(menu);
}
public void createSearchView(){
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.search_menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
searchView = findViewById(R.id.search_view);
searchView.setMenuItem(searchItem);
expandableLayout = findViewById(R.id.expandable_layout);
DatabaseReader.java Line 64-89
public static void readDataByKey(String account_key, DatabaseReference ref, final OnGetDataListener listener) {
listener.onStart();
Query query = ref.orderByKey().equalTo(account_key);
query.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
listener.dataRetrieved(dataSnapshot);
}
@Override
public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
}
@Override
public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
listener.onFailure();
}
});
}
Any help would be greatly appreciated. Thanks!
You may run into a race condition. You may have invoked createSearchView before the system calls onCreateOptionsMenu, so menu is null.
Try to have onCreateOptionsMenu invoke createSearchView after line:
this.menu = menu;