I have searched several StackOverflow questions such as:
Android app crashing when displaying firebase database entries
Is it necessary to add an AuthStateListener in every activity of Android Firebase?
App crashes with java.lang.NullPointerException
FirebaseAuth.getCurrentUser() is returning null value
android- java.lang.NullPointerException using getCurrentUser firebase auth
application crashes during the first launch while using FirebaseAuthentication
What is a NullPointerException, and how do I fix it?
And finally the closest question regarding to the problem I am facing:
Getting Null Object Reference on getCurrentUser().getUid() on Fragment
I have not found an answer yet. In the last link, a StackOverflow member explained that the NullPointerException happens because somehow the app ignores the redirection from the MainActivity to the LoginActivity in the case of getCurrentUser().getUid() == null and executes the ChatFragment, where the NullPointerException occurs.
My app had this kind of problem at the beginning on the Emulator, but somehow it works fine on the Emulator.
But now, I tried to install the app in my physical device and the app is crashing. I get the NullPointerException because the user is not yet signed in.
My app is similar to WhatsApp ChatApp. It has sliding TabLayout with two fragments. My app launchs the MainActivity which should redirect the AppUser to LoginActivity in case of first use of the app.
Here is my MainActivity
public class MainPageActivity extends AppCompatActivity implements GroupListAdapter.DataChangeListener {
public static final int PERMISSIONS_MULTIPLE_REQUEST = 123;
private Toolbar mToolBar;
private ViewPager mViewPager;
private TabLayout mTabLayout;
private TabsAccessAdapter mTabsAcessAdapter;
private FirebaseAuth mAuth;
private DatabaseReference RootRef;
private String currentUserID;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_page);
FirebaseApp.initializeApp(this);
mAuth = FirebaseAuth.getInstance();
RootRef = FirebaseDatabase.getInstance().getReference();
mToolBar = (Toolbar) findViewById(R.id.main_page_toolbar);
setSupportActionBar(mToolBar);
getSupportActionBar().setTitle("MyApp");
mViewPager = (ViewPager) findViewById(R.id.tabs_pager);
mTabsAcessAdapter = new TabsAccessAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mTabsAcessAdapter);
mTabLayout = (TabLayout) findViewById(R.id.tablayout);
mTabLayout.setupWithViewPager(mViewPager);
getPermissions();
}
private void getPermissions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.WRITE_CONTACTS,Manifest.permission.READ_CONTACTS,
Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE},PERMISSIONS_MULTIPLE_REQUEST);
}
}
@Override
protected void onStart() {
super.onStart();
Log.i("debinf mainpage", "onStart");
FirebaseAuth.getInstance().addAuthStateListener(new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
FirebaseUser currentUser = firebaseAuth.getCurrentUser();
if (currentUser == null) {
//Here is the place to redirect the AppUser to LoginActivity
sendUserToLoginActivity();
}else {
VerifyUserExistance();
}
}
});
}
private void VerifyUserExistance() {
String currentUserID = mAuth.getCurrentUser().getUid();
RootRef.child("user").child(currentUserID).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
Toast.makeText(MainPageActivity.this, "Bem vindo(a)!", Toast.LENGTH_SHORT).show();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
// Dealing with MENU > starts here
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.options_menu,menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
if (item.getItemId() == R.id.main_logout_option) {
mAuth.signOut();
sendUserToLoginActivity();
}
if (item.getItemId() == R.id.main_settings_option) {
//sendUserToSettingsActivity();
Toast.makeText(this, "Settings from MainAct", Toast.LENGTH_SHORT).show();
}
return false;
}
private void sendUserToLoginActivity() {
Intent loginIntent = new Intent(MainPageActivity.this,LoginActivity.class);
loginIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(loginIntent);
}
@Override
public void onDataSetChanged(String groupKeyFromSender, boolean addToCall) {
String tag = "android:switcher:" + R.id.tabs_pager + ":" + 1;
CallFragment rf = (CallFragment) getSupportFragmentManager().findFragmentByTag(tag);
rf.getDataFromGroupFragment(groupKeyFromSender, addToCall);
}
}
Here is my LoginActivity which should be called by MainActivity in the first usage, but it isn't.
public class LoginActivity extends AppCompatActivity {
private EditText mPhoneNumber, mCode;
private Button mSend;
private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks;
String mVerificationId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
FirebaseApp.initializeApp(this);
userIsLoggedIn();
mPhoneNumber = findViewById(R.id.phoneNumber);
mCode = findViewById(R.id.code);
mSend = findViewById(R.id.send);
mSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mVerificationId != null) {
verifyPhoneNumberWithCode();
} else {
startPhoneNumberVerification();
}
}
});
mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
@Override
public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {
sighInWithPhoneAuthCredential(phoneAuthCredential);
}
@Override
public void onVerificationFailed(FirebaseException e) {
}
@Override
public void onCodeSent(String verificationId, PhoneAuthProvider.ForceResendingToken forceResendingToken) {
super.onCodeSent(verificationId, forceResendingToken);
mVerificationId = verificationId;
mSend.setText("Enviar codigo");
}
};
}
private void verifyPhoneNumberWithCode(){
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(mVerificationId, mCode.getText().toString());
sighInWithPhoneAuthCredential(credential);
}
private void sighInWithPhoneAuthCredential(PhoneAuthCredential phoneAuthCredential) {
FirebaseAuth.getInstance().signInWithCredential(phoneAuthCredential).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
//userIsLoggedIn();
final FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
// I think add child named user and inside other child named userId = user.getUid()
if (user != null) {
// Do not forget to add database implementation in the gradle (module app)
final DatabaseReference mUserDB = FirebaseDatabase.getInstance().getReference().child("user").child(user.getUid());
mUserDB.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if (!dataSnapshot.exists()) {
// if user has never loged in, add a new user
Map<String, Object> userMap = new HashMap<>();
userMap.put("phone", user.getPhoneNumber());
//userMap.put("name", user.getPhoneNumber());
userMap.put("name", "babaloo");
mUserDB.updateChildren(userMap);
}
userIsLoggedIn();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
}
}
});
}
private void userIsLoggedIn() {
FirebaseAuth.getInstance().addAuthStateListener(new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
startActivity(new Intent(getApplicationContext(), MainPageActivity.class));
finish();
return;
}
}
});
}
private void startPhoneNumberVerification() {
PhoneAuthProvider.getInstance().verifyPhoneNumber(
mPhoneNumber.getText().toString(),60,
TimeUnit.SECONDS, this, mCallbacks);
}
}
And here is the onCreateView of the GroupFragment where the NullPointerException happens.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.group_fragment, container, false);
groupTablePath = getContext().getFilesDir().getPath()+"/GroupDataBase/";
rootPath = Environment.getExternalStorageDirectory() + "/";
mAuth = FirebaseAuth.getInstance();
currentUser = mAuth.getCurrentUser().getUid();
GroupRef = FirebaseDatabase.getInstance().getReference().child("Group");
UserRef = FirebaseDatabase.getInstance().getReference().child("user");
StoreRef = FirebaseStorage.getInstance().getReference();
FloatingActionButton findUser = (FloatingActionButton) view.findViewById(R.id.addContact);
findUser.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(view.getContext(), FindUserActivity.class));
}
});
//getPermissions();
CreateRootFolder();
initializeRecyclerView();
loadGroupListDatabase();
populateTeamTableInternet();
OwnerGroupUploadClientListTable();
updateClientListInternet();
// Inflate the layout for this fragment
return view;
}
This part of the error
at com.example.aliton.myapp.Fragments.GroupFragment.onCreateView(GroupFragment.java:107)
corresponds to this line of the code in the onCreateView of the GroupFragment:
currentUser = mAuth.getCurrentUser().getUid();
And here is FATAL error:
02-09 20:24:10.950 24837-24837/com.example.aliton.myapp E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.NullPointerException
at com.example.aliton.myapp.Fragments.GroupFragment.onCreateView(GroupFragment.java:107)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2439)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1460)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:802)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2625)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2411)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)
at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:2243)
at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:654)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:146)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1244)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1092)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1622)
at android.view.View.measure(View.java:15294)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:665)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:447)
at android.view.View.measure(View.java:15294)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4818)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:143)
at android.view.View.measure(View.java:15294)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4818)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1421)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:712)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:605)
at android.view.View.measure(View.java:15294)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4818)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at android.view.View.measure(View.java:15294)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4818)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1421)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:712)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:605)
at android.view.View.measure(View.java:15294)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4818)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2432)
at android.view.View.measure(View.java:15294)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1872)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1115)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1296)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1013)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4245)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
at android.view.Choreographer.doCallbacks(Choreographer.java:555)
at android.view.Choreographer.doFrame(Choreographer.java:525)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:153)
at android.app.ActivityThread.main(ActivityThread.java:5076)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
at com.
I appreciate any help.