我是使用Firebase在Android應用上工作的學生。我一直在嘗試設置Firebase身份驗證,但我一直收到空ptr例外的錯誤。Firebase身份驗證getcurrentUser java.lang.NullPointerException
用戶被放在
LoginActivity.java
屏幕使用谷歌,登錄API簽署並得到認證與火力地堡。然後用戶轉到下一個活動
MainActivity.java
。
它看起來像代碼:FirebaseUser user = firebaseAuth.getCurrentUser();
在MainActivity.java
返回空值,我不知道如何避免這個!
下面是我找到的相關跟蹤:
FATAL EXCEPTION: main
Process: joroze.com.roomifer, PID: 23176
java.lang.RuntimeException: Unable to start activity ComponentInfo{joroze.com.roomifer/joroze.com.roomifer.MainActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5021)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:827)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:643)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at joroze.com.roomifer.MainActivity.onCreate(MainActivity.java:126)
at android.app.Activity.performCreate(Activity.java:5426)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1090)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5021)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:827)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:643)
at dalvik.system.NativeStart.main(Native Method)
LoginActivity.java
public class LoginActivity extends AppCompatActivity implements
GoogleApiClient.OnConnectionFailedListener,
View.OnClickListener {
private static final String TAG = "SignInActivity";
private static final int RC_SIGN_IN = 9001;
// [START declare_auth]
private FirebaseAuth mAuth;
// [END declare_auth]
// [START declare_auth_listener]
private FirebaseAuth.AuthStateListener mAuthListener;
// [END declare_auth_listener]
private GoogleApiClient mGoogleApiClient;
private ProgressDialog mProgressDialog;
/**
* Id to identity READ_CONTACTS permission request.
*/
private static final int REQUEST_READ_CONTACTS = 0;
private DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
// Button listeners
findViewById(R.id.sign_in_button).setOnClickListener(this);
// [START configure_signin]
// Configure sign-in to request the user's ID, email address, and basic
// profile. ID and basic profile are included in DEFAULT_SIGN_IN.
// Configure Google Sign In
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build();
// [END configure_signin]
// [START build_client]
// Build a GoogleApiClient with access to the Google Sign-In API and the
// options specified by gso.
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
// [END build_client]
// [START initialize_auth]
mAuth = FirebaseAuth.getInstance();
// [END initialize_auth]
// [START auth_state_listener]
mAuthListener = new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
// User is signed in
Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid());
} else {
// User is signed out
Log.d(TAG, "onAuthStateChanged:signed_out");
}
}
};
// [END auth_state_listener]
// [START customize_button]
// Set the dimensions of the sign-in button.
SignInButton signInButton = (SignInButton) findViewById(R.id.sign_in_button);
signInButton.setSize(SignInButton.SIZE_STANDARD);
// [END customize_button]
}
@Override
public void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthListener);
OptionalPendingResult<GoogleSignInResult> opr = Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient);
if (opr.isDone()) {
// If the user's cached credentials are valid, the OptionalPendingResult will be "done"
// and the GoogleSignInResult will be available instantly.
Log.d(TAG, "Got cached sign-in");
GoogleSignInResult result = opr.get();
handleSignInResult(result);
} else {
// If the user has not previously signed in on this device or the sign-in has expired,
// this asynchronous branch will attempt to sign in the user silently. Cross-device
// single sign-on will occur in this branch.
showProgressDialog();
opr.setResultCallback(new ResultCallback<GoogleSignInResult>() {
@Override
public void onResult(GoogleSignInResult googleSignInResult) {
hideProgressDialog();
handleSignInResult(googleSignInResult);
}
});
}
}
// [START onActivityResult]
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
if (requestCode == RC_SIGN_IN) {
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
handleSignInResult(result);
}
}
// [END onActivityResult]
// [START handleSignInResult]
private void handleSignInResult(GoogleSignInResult result) {
Log.d(TAG, "handleSignInResult:" + result.isSuccess());
if (result.isSuccess()) {
// Signed in successfully, show authenticated UI.
GoogleSignInAccount acct = result.getSignInAccount();
firebaseAuthWithGoogle(acct);
Intent nextActivity = new Intent(this, MainActivity.class);
startActivity(nextActivity);
} else {
Log.d(TAG, "Currently signed out");
// Signed out, show unauthenticated UI.
}
}
// [END handleSignInResult]
// [START signIn]
private void signIn() {
Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
startActivityForResult(signInIntent, RC_SIGN_IN);
}
// [END signIn]
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
// An unresolvable error has occurred and Google APIs (including Sign-In) will not
// be available.
Log.d(TAG, "onConnectionFailed:" + connectionResult);
Toast.makeText(this, "Google Play Services error.", Toast.LENGTH_SHORT).show();
}
private void showProgressDialog() {
if (mProgressDialog == null) {
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("Loading...");
mProgressDialog.setIndeterminate(true);
}
mProgressDialog.show();
}
private void hideProgressDialog() {
if (mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.hide();
}
}
@Override
public void onClick(View v) {
signIn();
}
// [START on_stop_remove_listener]
@Override
public void onStop() {
super.onStop();
if (mAuthListener != null) {
mAuth.removeAuthStateListener(mAuthListener);
}
}
// [END on_stop_remove_listener]
// [START auth_with_google]
private void firebaseAuthWithGoogle(GoogleSignInAccount acct) {
Log.d(TAG, "firebaseAuthWithGoogle:" + acct.getId());
// [START_EXCLUDE silent]
showProgressDialog();
// [END_EXCLUDE]
AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
Log.d(TAG, "signInWithCredential:onComplete:" + task.isSuccessful());
// If sign in fails, display a message to the user. If sign in succeeds
// the auth state listener will be notified and logic to handle the
// signed in user can be handled in the listener.
if (!task.isSuccessful()) {
Log.w(TAG, "signInWithCredential", task.getException());
Toast.makeText(LoginActivity.this, "Authentication failed.",
Toast.LENGTH_SHORT).show();
}
// [START_EXCLUDE]
hideProgressDialog();
// [END_EXCLUDE]
}
});
}
// [END auth_with_google]
}
MainActivity.java
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, CreateGroupDialogFragment.CreateGroupDialogListener {
private static final String TAG = "SignInActivity";
FirebaseManageJSON fbmjson = new FirebaseManageJSON(this);
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
FirebaseUser mCurrentUser;
GoogleApiClient mGoogleApiClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAuth = FirebaseAuth.getInstance();
mAuthListener = new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
// Currently signed in
mCurrentUser = user;
clientUser = new User(mCurrentUser.getUid(), mCurrentUser.getDisplayName(), mCurrentUser.getEmail());
writeNewUser(clientUser);
} else {
signOut();
}
}
};
// [START configure_signin]
// Configure sign-in to request the user's ID, email address, and basic
// profile. ID and basic profile are included in DEFAULT_SIGN_IN.
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build();
// [END configure_signin]
// [START build_client]
// Build a GoogleApiClient with access to the Google Sign-In API and the
// options specified by gso.
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
// [END build_client]
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
showCreateGroupDialog();
}
});
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
View hView = navigationView.getHeaderView(0);
TextView userNameView = (TextView) hView.findViewById(R.id.usernameView);
TextView emailView = (TextView) hView.findViewById(R.id.emailView);
ImageView profileImageView = (ImageView) hView.findViewById(R.id.profileImageView);
if (mCurrentUser.getDisplayName() != null)
userNameView.setText(mCurrentUser.getDisplayName());
if (mCurrentUser.getEmail() != null)
emailView.setText(mCurrentUser.getEmail());
if (mCurrentUser.getPhotoUrl().toString() != null)
Glide.with(this).load(mCurrentUser.getPhotoUrl().toString()).into(profileImageView);
drawer.openDrawer(GravityCompat.START);
}
@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
// User should not need to go to the previous activity this way
//super.onBackPressed();
}
}
@Override
public boolean onCreateOptionsMenu (Menu menu){
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected (MenuItem item){
String message = "Roomifer is awesome!";
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("text/plain");
share.putExtra(Intent.EXTRA_TEXT, message);
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_menu) {
startActivity(Intent.createChooser(share, "Share using Messenger"));
return true;
}
return super.onOptionsItemSelected(item);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected (MenuItem item){
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_camera) {
// Handle the camera action
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_signout) {
signOut();
} else if (id == R.id.nav_deleteAccount) {
revokeAccess();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
@Override
public void onConnected (@Nullable Bundle bundle){
}
@Override
public void onConnectionSuspended (int i){
mGoogleApiClient.connect();
}
@Override
public void onConnectionFailed (@NonNull ConnectionResult connectionResult){
Log.d(TAG, "Connection FAILED!");
}
public void signOut() {
// Firebase sign out
FirebaseAuth.getInstance().signOut();
// Google sign out
Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
new ResultCallback<Status>() {
@Override
public void onResult(Status status) {
// Firebase sign out
mAuth.signOut();
if (status.isSuccess())
Log.d(TAG, "Log Out successful!");
else
Log.d(TAG, "Log Out failed!");
// finish this activity, and go back to the sign-in activity screen
finish();
}
});
}
public void revokeAccess() {
Auth.GoogleSignInApi.revokeAccess(mGoogleApiClient).setResultCallback(
new ResultCallback<Status>() {
@Override
public void onResult(Status status) {
// Firebase sign out
mAuth.signOut();
deleteAccount(clientUser);
if (status.isSuccess())
Log.d(TAG, "Revoke successful!");
else
Log.d(TAG, "Revoke failed!");
// finish this activity, and go back to the sign-in activity screen
finish();
}
});
}
protected void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthListener);
//Snackbar snackbar = Snackbar.make(this.findViewById(R.id.mainSnackBarView), "Signed in as " + clientUser.getUserName(), Snackbar.LENGTH_SHORT);
//snackbar.show();
}
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
if (mAuthListener != null) {
mAuth.removeAuthStateListener(mAuthListener);
}
}
}
提前感謝!
嗨,鮑勃!接得好。我已經添加了,但是我仍然從'MainActivity.java:126'開始得到空例外: 在這些行上,我嘗試從Firebase用戶那裏獲取值:'mCurrentUser.getDisplayName' ....但它返回null。 你有什麼線索可以避免這種情況嗎?感謝您的幫助! – Jordan
我更新了我的答案。 –
非常感謝你鮑勃!這絕對有效,你節省了我的開發時間小時! 我想提一下,解決方案後出現了另一個錯誤。我必須在'AuthStateListener'之前移動'GoogleAPI'代碼,否則就會說GoogleAPIClient尚未連接。 無論現在都好! – Jordan