2

我按照说明执行Google登录: https://firebase.google.com/docs/auth/android/google-signin#authenticate_with_firebase 身份验证和登录工作正常,用户已通过身份验证并签名-in和监听器被调用:Firebase 3在第一次登录Google后拒绝,第二次登录后工作

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"); 
      } 
     } 

然而,试图从具有标准的安全规则的用户节点/路径阅读时:

"users": { 
    "$user_id": { 
     ".read": "auth !== null && auth.uid === $user_id", 
     ".write": "auth !== null" 
    } 
    } 

与后手动触发以下代码:

DatabaseReference userRef = FirebaseDatabase.getInstance().getReference("users"); 
userRef.child(uid).addListenerForSingleValueEvent(
     new ValueEventListener() { 
      @Override 
      public void onDataChange(DataSnapshot data) { 
       ... 
      } 
      @Override 
      public void onCancelled(DatabaseError error) { 
       Log.w(TAG, "fb sync onCancelled: " + error.getMessage()); 
      } 
     }); 

onCancelled被称为与 “权限被拒绝”。该uid是正确的,等于为返回由firebaseAuth.getCurrentUser().getUid()

现在重要的是,一切,如果我注销和重新登录的,或者如果我终止,并重新启动应用程序正常工作的用户ID 。所以我猜想在初始登录后FirebaseAuth状态必定有问题,或者我可能再次错过某些内容..?

测试firebase-*:9.0.2play-services-auth:9.0.2以及9.2.0

+1

你能告诉它是如何失败的一个完整的最少的样品?例如:你什么时候设置'uid'的值?你什么时候附加听众?创建这样的[MCVE](http://stackoverflow.com/help/mcve)是隔离问题的好机会,并且使我们更容易提供帮助。 –

+0

从这里看起来不错。需要更多的代码。 – devprashant

回答

0

感谢弗兰克先生的建议,我已经成功地查明罪魁祸首。 当用户在匿名登录(我没有考虑到)登录时发生问题。因此,解决方法是在尝试使用Google登录之前注销匿名用户(FirebaseAuth.getInstance().sign_out()),但我认为这仍然是不受欢迎的行为,因为这会导致链接帐户出现问题。

下面就来重现问题的例子:

public class TestAuthGoogle extends AppCompatActivity implements GoogleApiClient.OnConnectionFailedListener { 

    static private final String TAG = TestAuthGoogle.class.getSimpleName(); 
    private GoogleApiClient mGoogleApiClient; 
    public static final int RC_SIGN_IN = 9001; 
    private Handler mHandler = new Handler(); 

    @Override 
    public void onStart() { 
     super.onStart(); 

     signInAnonymously(); 

     mHandler.postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       signInGoogle(); 
      } 
     },5000); 
    } 


    void signInAnonymously() { 
     FirebaseAuth.getInstance().signInAnonymously() 
       .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() { 
        @Override 
        public void onComplete(@NonNull Task<AuthResult> task) { 
         Log.d(TAG, "signInAnonymously:onComplete:" + task.isSuccessful()); 
         if (!task.isSuccessful()) { 
          Log.w(TAG, "signInAnonymously", task.getException()); 
         } 
        } 
       }); 
    } 

    void signInGoogle() { 
     GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) 
       .requestIdToken(getString(R.string.my_web_client_id)) 
       .requestEmail() 
       .build(); 

     mGoogleApiClient = new GoogleApiClient.Builder(TestAuthGoogle.this) 
       .enableAutoManage(TestAuthGoogle.this, TestAuthGoogle.this) 
       .addApi(Auth.GOOGLE_SIGN_IN_API, gso) 
       .build(); 

     Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); 
     startActivityForResult(signInIntent, RC_SIGN_IN); 
    } 

    @Override 
    public void onActivityResult(int requestCode, int resultCode, Intent data) { 
     super.onActivityResult(requestCode, resultCode, data); 
     if (requestCode == RC_SIGN_IN) { 
      GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data); 
      if (result.isSuccess()) { 
       GoogleSignInAccount account = result.getSignInAccount(); 
       firebaseAuthWithGoogle(account); 
       Log.d(TAG,"Authenticated"); 
      } else { 
       Log.d(TAG,"Authentication failed"); 
      } 
     } 
    } 

    private void firebaseAuthWithGoogle(GoogleSignInAccount acct) { 
     Log.d(TAG, "firebaseAuthWithGoogle:" + acct.getId()); 
     AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null); 
     FirebaseAuth.getInstance().signInWithCredential(credential) 
       .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() { 
        @Override 
        public void onComplete(@NonNull Task<AuthResult> task) { 
         Log.d(TAG, "signInWithCredential:onComplete:" + task.isSuccessful()); 
         if (task.isSuccessful()) { 
          Log.d(TAG,"Signed in"); 
          mHandler.postDelayed(new Runnable() { 
           @Override 
           public void run() { 
            readFromDatabase(); 
           } 
          },5000); 
         } else { 
          Log.w(TAG, "signInWithCredential: " + task.getException().getMessage()); 
         } 
        } 
       }); 
    } 

    void readFromDatabase() { 
     Log.d(TAG,"read from db"); 
     DatabaseReference uRef = FirebaseDatabase.getInstance().getReference("users"); 
     uRef.child(FirebaseAuth.getInstance().getCurrentUser().getUid()).addListenerForSingleValueEvent(
       new ValueEventListener() { 
        @Override 
        public void onDataChange(DataSnapshot data) { 
         Log.d(TAG, "fb onDataChange: " + data.getValue()); 
        } 
        @Override 
        public void onCancelled(DatabaseError error) { 
         Log.w(TAG, "fb onCancelled: " + error.getMessage()); 
        } 
       }); 
    } 

    @Override 
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { 
     Log.d(TAG,"onConnectionFailed"); 
    } 

} 
1

我对Firebase实时数据库的观察。

它添加到数据库(几毫秒)之前缓存在服务器端的数据。

结果:

读操作是几毫秒的时间比写操作快。

  • 发生了什么事您的要求:
    • 到达服务器并要求其仍然没有实时数据库中的数据。
  • 为什么有这么:
    • ,因为它的缓存,仍然要添加到实时数据库。
    • 所有这些缓存和添加数据到实时数据库只需要几毫秒的时间,但它在添加后立即调用数据时很重要,因为您的获取数据请求已在创建节点之前到达服务器。
    • 这就是为什么它显示权限被拒绝。
  • 当这种情况不会发生:

    • 如果您的设备使用低速互联网连接,你的请求到达有1-3秒的延迟火力地堡服务器,这种自然发生的。所以这个问题不会出现在那里。
  • 什么现在要做的:

    • 请求数据首次之前刚刚推出的2-3秒的延迟。
    • 这给了身份验证,节点创建和添加数据足够时间完成的整个操作。
    • 从那里一切都将平稳。
+0

如果您需要更多帮助,请随时发表评论。 – devprashant

+0

登录和数据请求之间的时间间隔长于2-3秒。该请求是手动触发的,我已经在登录后几分钟尝试过,但它被拒绝,只有在重新启动或重新登录后才能使用。 –

+0

需要更多代码。你可以分享项目吗? – devprashant

相关问题