问题
I know I can see so many questions on this topic on stackoverflow and I have tried almost all of them and haven't worked yet so this is my only option to post a new question.
My problem is FirebaseAuth.getInstance always return null even though I have initialized the FirebaseApp. My main purpose is to use phone authenticaiton from firebase and I have enabled it in firebase console.
Things I have done-
- Built firebase project in firebase console
- Added SHA-1 key
- downloaded the json file and added it to app level in my android project
- Multiple times of invalidate/restart in android studio
- Multiple times of debugging while trying to getInstance of firebaseAuth in different activity life cycle functions
- Tried to integrate FirebaseUI but still getInstance returns null and firebaseUI does not even start
- changing different version of FirebaseAuth
- checking dependencies in gradle file again and again
App Level Gradle
//apply plugin: 'kotlin-android'
apply plugin: 'com.android.application'
apply plugin: 'androidx.navigation.safeargs'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-android'
apply plugin: 'com.google.gms.google-services'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.ajoobee.mm"
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
dataBinding {
enabled = true
}
compileOptions {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
//noinspection GradleCompatible
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta2'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.navigation:navigation-fragment:2.0.0-rc02'
implementation 'androidx.navigation:navigation-ui:2.0.0-rc02'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
//add kotlin
/* implementation "androidx.core:core-ktx:1.0.1"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"*/
implementation "com.github.leonardoxh:retrofit2-livedata-adapter:1.1.2"
//Internet Checker
implementation 'com.treebo:internetavailabilitychecker:1.0.2'
// Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
implementation 'com.squareup.okhttp3:okhttp:3.11.1'
implementation 'com.squareup.okhttp3:logging-interceptor:3.4.1'
//Android Jetpack
implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.1.0'
// implementation "android.arch.lifecycle:extensions:1.1.1"
//ButterKnife
implementation 'com.jakewharton:butterknife:10.2.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.0'
//Dagger implementation 'com.google.dagger:dagger-android:2.17'
implementation 'com.google.dagger:dagger-android-support:2.17'
annotationProcessor 'com.google.dagger:dagger-android-processor:2.17'
/* Dagger2 - default dependency */
annotationProcessor 'com.google.dagger:dagger-compiler:2.17'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
//circle image view
implementation 'de.hdodenhof:circleimageview:3.0.1'
//room database
implementation 'androidx.room:room-runtime:2.1.0'
annotationProcessor 'androidx.room:room-compiler:2.1.0'
implementation 'com.jakewharton.timber:timber:4.7.1'
//ImagePicker and Glide
implementation group: 'com.zhihu.android', name: 'matisse', version: '0.5.2'
implementation 'com.github.bumptech.glide:glide:4.9.0'
//SummerNote
implementation 'in.nashapp.androidsummernote:androidsummernote:1.0.5'
//uCrop
implementation 'com.github.yalantis:ucrop:2.2.4-native'
//roundedImageView
implementation 'com.makeramen:roundedimageview:2.3.0'
//progressBarChart
implementation 'com.ramijemli.percentagechartview:percentagechartview:0.3.1'
//googleLocation
implementation "com.google.android.gms:play-services-location:17.0.0"
implementation 'com.google.android.libraries.places:places:2.0.0'
//implementation project(':multiselectspinner')
implementation 'com.droidninja:filepicker:2.2.1'
//firebase
implementation 'com.google.firebase:firebase-auth:19.1.0'
implementation 'com.google.android.gms:play-services-auth:17.0.0'
}
apply plugin: 'com.google.gms.google-services'
my project level Gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
//ext.kotlin_version = '1.3.30'
repositories {
google()
jcenter()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.30"
classpath 'com.android.tools.build:gradle:3.5.1'
classpath 'android.arch.navigation:navigation-safe-args-gradle-plugin:1.0.0'
classpath 'androidx.navigation:navigation-safe-args-gradle-plugin:2.1.0'
classpath 'com.google.gms:google-services:4.3.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
google()
maven { url "https://jitpack.io" }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
My Fragment
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.navigation.NavOptions;
import androidx.navigation.Navigation;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.ForegroundColorSpan;
import android.text.style.UnderlineSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import com.ajoobee.mm.Constants;
import com.ajoobee.mm.Data.Network.Response.ServerResult;
import com.ajoobee.mm.Data.Network.Retrofit.AuthenticationInterceptor;
import com.ajoobee.mm.Employer.UI.Home.Profile.PopUpWindow.CityPopUpWindow;
import com.ajoobee.mm.Employer.UI.Home.Profile.UpdateCompanyViewModel;
import com.ajoobee.mm.JobSeeker.UI.Home.Profile.JobSeekerProfileViewModel;
import com.ajoobee.mm.R;
import com.ajoobee.mm.Util.ErrorDialog;
import com.ajoobee.mm.Util.Util;
import com.ajoobee.mm.ViewModelFactory;
import com.ajoobee.mm.databinding.JobseekerFragmentRegisterBinding;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseException;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.auth.PhoneAuthCredential;
import com.google.firebase.auth.PhoneAuthProvider;
import com.google.gson.JsonObject;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import dagger.android.support.AndroidSupportInjection;
public class JobSeekerRegisterFragment extends Fragment {
private JobseekerFragmentRegisterBinding binding;
private JobSeekerProfileViewModel jobSeekerProfileViewModel;
private UpdateCompanyViewModel updateCompanyViewModel;
private CityPopUpWindow cityPopUpWindow;
private int city;
private boolean first = true;
private ErrorDialog errorDialog;
@Inject
ViewModelFactory viewModelFactory;
@Inject
AuthenticationInterceptor authenticationInterceptor;
private FirebaseAuth mAuth;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = DataBindingUtil.inflate(inflater, R.layout.jobseeker_fragment_register, container, false);
init();
if(this.getContext() != null){
FirebaseApp.initializeApp(this.getContext());
mAuth = FirebaseAuth.getInstance();
}
return binding.getRoot();
}
@Override
public void onStart() {
super.onStart();
FirebaseUser firebaseUser = mAuth.getCurrentUser();
if(firebaseUser != null){
Toast.makeText(this.getContext(), "Already Sign in ", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this.getContext(), "mAuth Still null ", Toast.LENGTH_SHORT).show();
}
}
private void init() {
if (this.getActivity() != null) {
if (this.getActivity().getIntent() != null) {
Intent intent = this.getActivity().getIntent();
if (intent.getBooleanExtra(Constants.LOGIN, false)) {
NavOptions navOptions = new NavOptions.Builder()
.setPopUpTo(R.id.jobSeekerEmailVeriRequiredFragment, true)
.build();
Navigation.findNavController(JobSeekerRegisterFragment.this.getActivity(), R.id.fragment).navigate(R.id.jobSeekerEmailVeriRequiredFragment, new Bundle(), navOptions);
}
}
}
if (this.getContext() != null) {
errorDialog = new ErrorDialog(this.getContext(), new ErrorDialog.OkButtonClick() {
@Override
public void onOkClick() {
}
});
binding.txtCity.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
if (first) {
cityPopUpWindow = new CityPopUpWindow(this.getContext(), binding.txtCity, city, id -> {
city = id;
cityPopUpWindow.dismiss();
cityPopUpWindow.opened = false;
binding.dropDownImageView.animate().rotation(0).start();
});
first = false;
}
});
jobSeekerProfileViewModel = ViewModelProviders.of(this, viewModelFactory).get(JobSeekerProfileViewModel.class);
updateCompanyViewModel = ViewModelProviders.of(this, viewModelFactory).get(UpdateCompanyViewModel.class);
//ClickableSpan
SpannableString spannableString = new SpannableString(getString(R.string.jobseeker_signup_already_account));
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(@NonNull View widget) {
Intent intent = new Intent(getActivity(), JobSeekerLogin.class);
JobSeekerRegisterFragment.this.startActivity(intent);
}
};
spannableString.setSpan(clickableSpan, 25, 30, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.activeControlColor)), 25, 30, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString.setSpan(new UnderlineSpan(), 0, spannableString.length(), 0);
binding.alreadyHaveAccountTextView.setText(spannableString);
binding.alreadyHaveAccountTextView.setMovementMethod(LinkMovementMethod.getInstance());
binding.alreadyHaveAccountTextView.setHighlightColor(Color.TRANSPARENT);
//ClickableSpan
//ClickListener
binding.txtCity.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
cityPopUpWindow.show();
if (cityPopUpWindow.opened) {
binding.dropDownImageView.animate().rotation(180).start();
} else {
binding.dropDownImageView.animate().rotation(0).start();
}
}
});
binding.btnRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// if (CheckCondition()) {
// sendToRegister();
// }
getVerificationCode();
}
});
//ClickListener
//City
updateCompanyViewModel.Api_City();
updateCompanyViewModel.observeCity().observe(this, listServerResult -> {
if (listServerResult != null) {
if (listServerResult.getResponse().getCode().equals("200")) {
if (cityPopUpWindow != null) {
if (cityPopUpWindow.cityPopUpAdapter != null) {
cityPopUpWindow.cityPopUpAdapter.addCity(listServerResult.getResult());
cityPopUpWindow.cityPopUpAdapter.notifyDataSetChanged();
}
}
}
}
});
//City
//Registration
jobSeekerProfileViewModel.observeRegistration().observe(this, new Observer<ServerResult<JsonObject>>() {
@Override
public void onChanged(ServerResult<JsonObject> jsonObjectServerResult) {
if (jsonObjectServerResult != null) {
if (jsonObjectServerResult.getResponse().getCode().equals("200")) {
if (jsonObjectServerResult.getResult() != null) {
if (jsonObjectServerResult.getResult().size() > 0) {
JsonObject jsonObject = jsonObjectServerResult.getResult().get(0);
if (JobSeekerRegisterFragment.this.getActivity() != null) {
authenticationInterceptor.tokenId = jsonObject.get("token").getAsString();
Navigation.findNavController(JobSeekerRegisterFragment.this.getActivity(), R.id.fragment).navigate(R.id.action_jobSeekerRegisterFragment_to_jobSeekerEmailVerificationFragment);
}
}
}
} else {
errorDialog.updateTitleAndShow(jsonObjectServerResult.getResponse().getMessage());
}
}
}
});
//Registration
}
}
private boolean CheckCondition() {
if (this.getContext() != null) {
if (Util.checkConnection(this.getContext())) {
if (binding.txtContactInfoEmail.getText().toString().isEmpty()) {
errorDialog.updateTitleAndShow(getString(R.string.signup_error_missing_email_or_phone));
return false;
} else {
if (!Util.checkEmail(binding.txtContactInfoEmail.getText().toString())) {
if (!Util.checkPhoneNumber(binding.txtContactInfoEmail.getText().toString())) {
errorDialog.updateTitleAndShow(getString(R.string.signup_error_missing_email_phone_valid));
return false;
}
}
}
if (binding.txtFullName.getText().toString().isEmpty()) {
errorDialog.updateTitleAndShow(getString(R.string.signup_error_missing_full_name));
return false;
}
if (binding.txtPasword.getText().toString().isEmpty()) {
errorDialog.updateTitleAndShow(getString(R.string.signup_error_missing_password));
return false;
} else {
if (binding.txtPasword.getText().toString().length() < 6 || !Util.checkPassword(binding.txtPasword.getText().toString())) {
errorDialog.updateTitleAndShow(getString(R.string.signup_error_password_character));
return false;
}
}
if (binding.txtConfirmPassword.getText().toString().isEmpty()) {
errorDialog.updateTitleAndShow(getString(R.string.signup_error_confirm_password));
return false;
}
if (binding.txtCity.getText().toString().isEmpty()) {
errorDialog.updateTitleAndShow(getString(R.string.signup_error_missing_location));
return false;
}
if (!binding.txtPasword.getText().toString().equals(binding.txtConfirmPassword.getText().toString())) {
errorDialog.updateTitleAndShow(getString(R.string.signup_error_missing_password_match));
return false;
}
return true;
} else {
errorDialog.updateTitleAndShow(getResources().getString(R.string.no_internet_connection));
return false;
}
} else {
return false;
}
}
private void getVerificationCode() {
if(mAuth != null){
PhoneAuthProvider.getInstance(mAuth).verifyPhoneNumber(
"09798423585", // Phone number to verify
60, // Timeout duration
TimeUnit.SECONDS, // Unit of timeout
this.getActivity(), // Activity (for callback binding)
new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
@Override
public void onVerificationCompleted(@NonNull PhoneAuthCredential phoneAuthCredential) {
Toast.makeText(getContext(), "Verification Completed", Toast.LENGTH_SHORT).show();
}
@Override
public void onVerificationFailed(@NonNull FirebaseException e) {
Toast.makeText(getContext(), "Verification failed", Toast.LENGTH_SHORT).show();
}
});
}
}
private void sendToRegister() {
com.ajoobee.mm.Data.Obj.JobSeeker.JobSeekerRegister jobSeekerRegister = new com.ajoobee.mm.Data.Obj.JobSeeker.JobSeekerRegister(
binding.txtFullName.getText().toString(),
binding.txtPasword.getText().toString(),
binding.txtContactInfoEmail.getText().toString(),
"",
"",
"",
"1",
""
);
if (this.getActivity() != null) {
((JobSeekerRegisterActivity) this.getActivity()).email = binding.txtContactInfoEmail.getText().toString();
}
jobSeekerProfileViewModel.Api_JobSeekerRegistration(jobSeekerRegister);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
AndroidSupportInjection.inject(this);
}
}
Error Message
java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.firebase.auth.FirebaseUser com.google.firebase.auth.FirebaseAuth.getCurrentUser()' on a null object reference
You can see that I tried to get current user onStart function but it ever failed. I debugged every lines and mAuth is always null.
回答1:
Finally found the answer, it was because of the
tools:node="replace"
in the manifest. Just remove it and it will work fine.
回答2:
fix this method:
@Override
public void onStart() {
super.onStart();
FirebaseUser firebaseUser = mAuth.getCurrentUser();//here u must have
//instance first then use the method
if(firebaseUser != null){
Toast.makeText(this.getContext(), "Already Sign in ",
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this.getContext(), "mAuth Still null ",
Toast.LENGTH_SHORT).show();
}
}
code below will work correct for u
@Override
public void onStart() {
super.onStart();
FirebaseApp.initializeApp(this.getContext());
mAuth = FirebaseAuth.getInstance();
FirebaseUser firebaseUser = getInstance(); //first try without this line
firebaseUser = mAuth.getCurrentUser();
if(firebaseUser != null){
Toast.makeText(this.getContext(), "Already Sign in ",
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this.getContext(), "mAuth Still null ",
Toast.LENGTH_SHORT).show();
}
}
来源:https://stackoverflow.com/questions/58496920/firebaseauth-getinstance-always-return-null