Android Studio - Firebase 在尝试签署 facebook 或 google 时返回 null

Posted

技术标签:

【中文标题】Android Studio - Firebase 在尝试签署 facebook 或 google 时返回 null【英文标题】:Android Studio - Firebase returns null when trying to sign facebook or google 【发布时间】:2018-10-20 08:32:49 【问题描述】:

当我尝试使用 FacebookGoogle 登录 Firebase 时,我的应用程序崩溃了,因为它没有使用 Firebase 创建新用户CreateNewUser().

Logcat:-

05-10 09:11:58.180 16986-16986/com.example.sefi.authenticationproject E/VideoAdapter: onCreateViewHolder() >> 05-10 09:11:58.191 16986-16986/com.example.sefi.authenticationproject E/VideoAdapter: onCreateViewHolder() > 0 05-10 09:11:58.203 16986-16986/com.example.sefi.authenticationproject E/androidRuntime: FATAL EXCEPTION: main 进程:com.example.sefi.authenticationproject,PID:16986 java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“java.lang.String java.lang.Object.toString()” 在 com.example.sefi.authenticationproject.adapter.VideoAdapter.onBindViewHolder(VideoAdapter.java:114) 在 com.example.sefi.authenticationproject.adapter.VideoAdapter.onBindViewHolder(VideoAdapter.java:32) 在 android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6482) 在 android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6515) 在 android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5458) 在 android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5724) 在 android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5563) 在 android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5559) 在 android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2229) 在 android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1556) 在 android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1516) 在 android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:608) 在 android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3693) 在 android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3410) 在 android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3962) 在 android.view.View.layout(View.java:18799) 在 android.view.ViewGroup.layout(ViewGroup.java:5952) 在 android.support.constraint.ConstraintLayout.onLayout(ConstraintLayout.java:1855) 在 android.view.View.layout(View.java:18799) 在 android.view.ViewGroup.layout(ViewGroup.java:5952) 在 android.widget.FrameLayout.layoutChildren(FrameLayout.java:323) 在 android.widget.FrameLayout.onLayout(FrameLayout.java:261) 在 android.view.View.layout(View.java:18799) 在 android.view.ViewGroup.layout(ViewGroup.java:5952) 在 android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741) 在 android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585) 在 android.widget.LinearLayout.onLayout(LinearLayout.java:1494) 在 android.view.View.layout(View.java:18799) 在 android.view.ViewGroup.layout(ViewGroup.java:5952) 在 android.widget.FrameLayout.layoutChildren(FrameLayout.java:323) 在 android.widget.FrameLayout.onLayout(FrameLayout.java:261) 在 com.android.internal.policy.DecorView.onLayout(DecorView.java:822) 在 android.view.View.layout(View.java:18799) 在 android.view.ViewGroup.layout(ViewGroup.java:5952) 在 android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2634) 在 android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2350) 在 android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1509) 在 android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7051) 在 android.view.Choreographer$CallbackRecord.run(Choreographer.java:927) 在 android.view.Choreographer.doCallbacks(Choreographer.java:702) 在 android.view.Choreographer.doFrame(Choreographer.java:638) 在 android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:913) 在 android.os.Handler.handleCallback(Handler.java:751) 在 android.os.Handler.dispatchMessage(Handler.java:95) 在 android.os.Looper.loop(Looper.java:154) 在 android.app.ActivityThread.main(ActivityThread.java:6692) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)

LogInActivity.java

public class LogInActivity extends Activity 

    public static final String TAG = "LogInActivity";
    private static final int RC_GOOGLE_SIGN_IN = 1001;

    private FirebaseAuth mAuth;
    private FirebaseAuth.AuthStateListener mAuthListener;

    private CallbackManager mCallbackManager;
    private AccessTokenTracker mAccessTokenTracker;
    private GoogleSignInClient mGoogleSignInClient;

    private EditText mEmail;
    private EditText mPass;
    private TextView mStatus;
    private boolean mIsSignup;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.log_in_activity);

        mEmail = findViewById(R.id.email_id);
        mPass = findViewById(R.id.password_id);
        mStatus = findViewById(R.id.status_id);

        firebaseAuthenticationInit();
        googleSigninInit();
        facebookLoginInit();
    

    @Override
    protected void onStart() 

        Log.e(TAG, "onStart() >>");

        super.onStart();

        mAuth.addAuthStateListener(mAuthListener);

        updateLoginStatus("N.A");

        Log.e(TAG, "onStart() <<");

    

    @Override
    protected void onStop() 

        Log.e(TAG, "onStop() >>");

        super.onStop();

        if (mAuthListener != null) 
            mAuth.removeAuthStateListener(mAuthListener);
        
        Log.e(TAG, "onStop() <<");

    

    public void onEmailPasswordAuthClick(View V) 

        Log.e(TAG, "onEmailPasswordAuthClick() >>");

        String email = mEmail.getText().toString();
        String pass = mPass.getText().toString();

        Task<AuthResult> authResult;
        boolean canContinue = checkIfEmailOrPasswordIsRequired(email, pass);
        if (canContinue == true)
        
            switch (V.getId()) 
                case R.id.sign_in_id:
                    //Email / Password sign-in
                    authResult = mAuth.signInWithEmailAndPassword(email, pass);
                    moveToNextScreenAfterValidation(authResult);
                    mIsSignup = false;
                    break;
                case R.id.sign_up_id:
                    //Email / Password sign-up
                    authResult = mAuth.createUserWithEmailAndPassword(email, pass);
                    mIsSignup = true;
                    moveToNextScreenAfterValidation(authResult);
                    break;
                default:
                    return;
            
            authResult.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() 

                @Override
                public void onComplete(@NonNull Task<AuthResult> task) 
                    Log.e(TAG, "Email/Pass Auth: onComplete() >> " + task.isSuccessful());

                    if (mIsSignup) 
                        createNewUser();
                    

                    if (!task.isSuccessful())
                    
                        Toast.makeText(LogInActivity.this, "User is already in use or there is a temporary problem", Toast.LENGTH_LONG).show();
                    
                    updateLoginStatus(task.isSuccessful() ? "N.A" : task.getException().getMessage());

                    Log.e(TAG, "Email/Pass Auth: onComplete() <<");
                
            );
        
        Log.e(TAG, "onEmailPasswordAuthClick() <<");
    

    public void signInAnonymously(View v) 
        mAuth.signInAnonymously()
                .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() 
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) 
                        if (task.isSuccessful()) 
                            // Sign in success, update UI with the signed-in user's information
                            Log.d(TAG, "signInAnonymously:success");
                            FirebaseUser user = mAuth.getCurrentUser();
                            Intent intent = new Intent(LogInActivity.this,StandupPlayerMain.class);
                            startActivity(intent);
                         else 
                            // If sign in fails, display a message to the user.
                            Log.w(TAG, "signInAnonymously:failure", task.getException());
                            Toast.makeText(LogInActivity.this, "Skip sign up failed", Toast.LENGTH_LONG).show();
                        
                    
                );
    

    public void onForgetPasswordClick(View V)
    
        Intent intent = new Intent(LogInActivity.this,ForgotMyPassword.class);
        startActivity(intent);
    

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) 


        Log.e(TAG, "onActivityResult () >>");

        super.onActivityResult(requestCode, resultCode, data);

        // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
        if (requestCode == RC_GOOGLE_SIGN_IN) 
            //Google Login...
            Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
            try 
                // Google Sign In was successful, authenticate with Firebase
                GoogleSignInAccount account = task.getResult(ApiException.class);
                firebaseAuthWithGoogle(account);
             catch (ApiException e) 
                // Google Sign In failed, update UI appropriately
                Log.e(TAG, "Google sign in failed", e);
                Toast.makeText(LogInActivity.this, "Google signing in falied", Toast.LENGTH_LONG).show();
                // ...
            
        

        mCallbackManager.onActivityResult(requestCode, resultCode, data);

        Log.e(TAG, "onActivityResult () <<");
    

    private void facebookLoginInit() 
        Log.e(TAG, "facebookLoginInit() >>");
        mCallbackManager = CallbackManager.Factory.create();
        LoginButton loginButton = findViewById(R.id.login_button);
        loginButton.setReadPermissions("email", "public_profile");
        loginButton.registerCallback(mCallbackManager, new FacebookCallback<LoginResult>() 
            @Override
            public void onSuccess(LoginResult loginResult) 
                Log.e(TAG, "facebook:onSuccess () >>" + loginResult);
                Log.e(TAG, "look for me");
                createNewUser();
                handleFacebookAccessToken(loginResult.getAccessToken());
                Log.e(TAG, "facebook:onSuccess () <<");
            

            @Override
            public void onCancel() 
                Log.e(TAG, "facebook:onCancel() >>");
                updateLoginStatus("Facebook login canceled");
                Log.e(TAG, "facebook:onCancel() <<");
            

            @Override
            public void onError(FacebookException error) 
                Log.e(TAG, "facebook:onError () >>" + error.getMessage());
                Toast.makeText(LogInActivity.this, "Facebook log in failed", Toast.LENGTH_LONG).show();
                updateLoginStatus(error.getMessage());
                Log.e(TAG, "facebook:onError <<");
            
        );

        mAccessTokenTracker = new AccessTokenTracker() 
            @Override
            protected void onCurrentAccessTokenChanged(AccessToken oldAccessToken,AccessToken currentAccessToken) 
                Log.e(TAG, "facebook:inside Token change <<");
                if (currentAccessToken == null)
                
                    mAuth.signOut();
                    updateLoginStatus("Facebook signuout");
                
                Log.e(TAG,"onCurrentAccessTokenChanged() >> currentAccessToken="+
                        (currentAccessToken !=null ? currentAccessToken.getToken():"Null") +
                        " ,oldAccessToken=" +
                        (oldAccessToken !=null ? oldAccessToken.getToken():"Null"));
            
        ;
        Log.e(TAG, "facebookLoginInit() <<");
    

    private void handleFacebookAccessToken(AccessToken token) 

        Log.e(TAG, "handleFacebookAccessToken () >>" + token.getToken());

        AuthCredential credential = FacebookAuthProvider.getCredential(token.getToken());
        mAuth.signInWithCredential(credential)
                .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() 
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) 
                        Log.e(TAG, "Facebook: onComplete() >> " + task.isSuccessful());
                        if(task.isSuccessful()==true)
                        
                            Intent intent = new Intent(LogInActivity.this,StandupPlayerMain.class);
                            startActivity(intent);
                        
                        updateLoginStatus(task.isSuccessful() ? "N.A" : task.getException().getMessage());

                        Log.e(TAG, "Facebook: onComplete() <<");
                    
                );

        Log.e(TAG, "handleFacebookAccessToken () <<");

    

    private void firebaseAuthenticationInit() 

        Log.e(TAG, "firebaseAuthenticationInit() >>");
        //Obtain reference to the current authentication
        mAuth = FirebaseAuth.getInstance();

        FirebaseUser user = mAuth.getCurrentUser();
        if (user != null)
        
            Intent intent = new Intent(LogInActivity.this,StandupPlayerMain.class);
            startActivity(intent);
        

        mAuthListener = new FirebaseAuth.AuthStateListener() 
            @Override
            public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) 
                Log.e(TAG, "onAuthStateChanged() >>");

                updateLoginStatus("N.A");

                Log.e(TAG, "onAuthStateChanged() <<");
            
        ;

        Log.e(TAG, "firebaseAuthenticationInit() <<");
    

    private void googleSigninInit() 

        Log.e(TAG, "googleSigninInit() >>" );

        // Configure Google Sign In
        GoogleSignInOptions gso = new GoogleSignInOptions
                .Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestIdToken(getString(R.string.default_web_client_id))
                .requestProfile()
                .requestEmail()
                .build();

        // Build a GoogleSignInClient with the options specified by gso.
        mGoogleSignInClient = GoogleSignIn.getClient(this, gso);

        findViewById(R.id.google_sign_in_button).setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View view) 
                Log.e(TAG, "look for me" + mAuth.getCurrentUser().toString());
                onGooglesignIn();
            
        );

        Log.e(TAG, "googleSigninInit() <<" );
    

    private void onGooglesignIn() 

        Log.e(TAG, "onGooglesignIn() >>" );
        createNewUser();
        Intent signInIntent = mGoogleSignInClient.getSignInIntent();
        startActivityForResult(signInIntent, RC_GOOGLE_SIGN_IN);

        Log.e(TAG, "onGooglesignIn() <<" );
    

    private boolean checkIfEmailOrPasswordIsRequired(String email,String password)
    
        boolean result = true;
        if (email.length() == 0)
        
            result = false;
            Toast.makeText(LogInActivity.this, "Email is missing", Toast.LENGTH_LONG).show();
        
        else if (password.length() == 0)
        
            result = false;
            Toast.makeText(LogInActivity.this, "Password is missing", Toast.LENGTH_LONG).show();
        
        return result;
    

    private void firebaseAuthWithGoogle(GoogleSignInAccount acct) 

        Log.e(TAG, "firebaseAuthWithGoogle() >>" + acct.getId());

        AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
        mAuth.signInWithCredential(credential)
                .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() 
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) 
                        updateLoginStatus(task.isSuccessful() ? "N.A" : task.getException().getMessage());
                        Log.e(TAG, "look for me");
                        Intent intent = new Intent(LogInActivity.this,StandupPlayerMain.class);
                        startActivity(intent);
                    
                );

        Log.e(TAG, "firebaseAuthWithGoogle() <<");

    

    private void moveToNextScreenAfterValidation(Task<AuthResult> authResult)
    
        Log.e(TAG, "emailPasswordVaildation () >>");
        authResult.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() 

            @Override
            public void onComplete(@NonNull Task<AuthResult> task) 
                Log.e(TAG, "emailPasswordVaildation outside if");
                if(task.isSuccessful() == true)
                
                    Log.e(TAG, "emailPasswordVaildation inside if");
                    //createNewUser();
                    Intent intent = new Intent(LogInActivity.this,StandupPlayerMain.class);
                    intent.putExtra("User Info",mAuth.getCurrentUser().getUid());
                    startActivity(intent);
                
            
        );
        Log.e(TAG, "emailPasswordVaildation () <<");
    

    private void updateLoginStatus(String details) 

        FirebaseUser user = mAuth.getCurrentUser();

        if (user == null) 
            mStatus.setText("SIGNED-OUT \ndetails:" + details);
         else 
            mStatus.setText("SIGNED-IN\nname:" + user.getDisplayName() +
                    "\nemail:" + user.getEmail() +
                    "\nuid:" + user.getUid() +
                    "\ndetails:" + details);
        
    

    private void createNewUser() 

        Log.e(TAG, "createNewUser() >>");

        FirebaseUser fbUser = mAuth.getCurrentUser();
        DatabaseReference userRef = FirebaseDatabase.getInstance().getReference("Users");
        if (fbUser == null) 
            Log.e(TAG, "createNewUser() << Error user is null");
            return;
        

        Log.e(TAG,userRef.toString());
        userRef.child(fbUser.getUid()).setValue(new User(fbUser.getEmail(),0,null));

        Log.e(TAG, "createNewUser() <<");
    

【问题讨论】:

请看creating an MCVE。在这种情况下,主要是最小的部分。 【参考方案1】:

我猜这是适配器中的一个错误,不在当前活动中。

您的日志显示:- 尝试在 com.example.sefi.authenticationproject.adapter.VideoAdapter.onBindViewHolder 的空对象引用上调用虚拟方法“java.lang.String java.lang.Object.toString()” (VideoAdapter.java:114)

您的问题与活动/片段有关,您可能正在使用适配器“VideoAdapter”,并且可能存在一些未定义的“视图”。

如果问题仍然存在,请使用调试器并逐行运行代码,并提供更详细和具体的问题。

【讨论】:

但是由于firebase的getCurrentUser返回null,所以没有创建用户实体,因此onBind失败

以上是关于Android Studio - Firebase 在尝试签署 facebook 或 google 时返回 null的主要内容,如果未能解决你的问题,请参考以下文章

Android Studio、谷歌 Firebase、谷歌地图

尝试从 Android Studio 添加 Firebase 项目时出错

Android Studio中的Firebase android jars文档/javadoc [重复]

无法在 android studio 中设置 firebase

Android Studio和Firebase中的权限被拒绝错误[重复]

从 Android Studio 中的片段将数据写入 Firebase