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

相關問題