2016-06-13 41 views
4

我爲我的應用設置了firebase存儲,並在應用和firebase控制檯中添加了匿名認證的代碼。Firebase突然停止工作,使用匿名認證

它工作在第一,但我不知道爲什麼它停止工作,說用戶沒有權限訪問

匿名身份驗證設置正確的對象,我沒有看到它的工作,代碼幾乎是像谷歌文檔火力地堡

的logcat:

d/FirebaseAuth:signInAnonymously:的onComplete:真
d/FirebaseAuth: onAuthStateChanged:signed_in:(隨機auth用戶ID)

...當我請求火力

E/StorageUtil項目:錯誤得到令牌java.util.concurrent.ExecutionException:com.google.firebase.FirebaseException:一個內部錯誤。 [遇到內部錯誤。] I/DpmTcmClient:RegisterTcmMonitor from:com.android.okhttp.TcmIdleTimerMonitor W/NetworkRequest:no auth 請求標記E/StorageException:發生StorageException。 用戶沒有權限訪問此對象。 代碼:-13021 HttpResult:403

有人可以幫忙嗎?

聲明變量

private FirebaseAuth mAuth; 
private FirebaseAuth.AuthStateListener mAuthListener; 

在onCreate方法

mAuthListener = new FirebaseAuth.AuthStateListener() { 
     @Override 
     public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { 
      FirebaseUser user = firebaseAuth.getCurrentUser(); 
      if (user != null) { 
       // User is signed in 
       Log.d("FirebaseAuth", "onAuthStateChanged:signed_in:" + user.getUid()); 
      } else { 
       // User is signed out 
       Log.d("FirebaseAuth", "onAuthStateChanged:signed_out"); 
      } 
      // ... 
     } 
    }; 
    mAuth.signInAnonymously() 
      .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() { 
       @Override 
       public void onComplete(@NonNull Task<AuthResult> task) { 
        Log.d("FirebaseAuth", "signInAnonymously: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("FirebaseAuth", "signInAnonymously", task.getException()); 
         Toast.makeText(SingleMemeEditor.this, "Authentication failed.", 
           Toast.LENGTH_SHORT).show(); 
        } 

        // ... 
       } 
      }); 

,並從存儲獲得方法:

Bitmap bmp; 
    final Context lContext = context; //getting the MainActivity Context 
    final String lFileName = fileName; //filename to download 
    final String lCatPath = catPath; //internal categorization folder 

    FirebaseStorage storage = FirebaseStorage.getInstance(); 
    // Create a storage reference from our app 
    StorageReference storageRef = storage.getReferenceFromUrl(context.getResources().getString(R.string.firebase_bucket)); 
    // Create a reference with an initial file path and name 
    StorageReference filesRef = storageRef.child("files/" + fileName); 
    try 
    { 
     final File localFile = File.createTempFile("images", "jpg"); 

     filesRef.getFile(localFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() 
     { 
      @Override 
      public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) 
      { 
       // Local temp file has been created 
       File file = new File(getDirectory(lContext) 
         + File.separator + lCatPath + File.separator + lFileName); 
       try 
       { 
        Boolean b = file.createNewFile(); 
        if(b) 
        { 
         FileInputStream in = new FileInputStream(localFile); 
         FileOutputStream out = new FileOutputStream(file); 

         // Transfer bytes from in to out 
         byte[] buf = new byte[(int)localFile.length()]; 
         int len; 
         while ((len = in.read(buf)) > 0) { 
          out.write(buf, 0, len); 
         } 
         in.close(); 
         out.close(); 
        } 
          Drawable.createFromPath(file.getPath())).getBitmap()); 
       } 
       catch (IOException ex) 
       { 
        // Handle any errors 
        Log.e("CopyingFromTemp", ex.getMessage()); 
       } 

      } 
     }).addOnFailureListener(new OnFailureListener() 
     { 
      @Override 
      public void onFailure(@NonNull Exception ex) 
      { 
       // Handle any errors 
       Log.e("FirebaseDownloadError", ex.getMessage()); 
      } 
     }); 
    } 
    catch(Exception ex) 
    { 
     Log.e("FirebaseDownloadError", ex.getMessage()); 
    } 

也是我使用標準的安全規則:

match /{allPaths=**} { 
     allow read, write: if request.auth != null; 
    } 
+0

顯示存儲的安全規則以及重現問題的最小代碼(此處的流程非常重要)。 –

+0

編輯帖子以添加您請求的內容 –

+0

不幸的是,代碼並未顯示如何確保用戶在上載圖像之前進行了身份驗證。在開始實際上傳之前,您可能需要添加一個簡單的檢查if(FirebaseAuth.getInstance()。getCurrentUser!0 null)'。 –

回答

4

正如Benjamin Wulfe所暗示的那樣,我在手機上刪除了應用程序的數據並且它工作正常,這意味着某些令牌數據存儲在手機中,而匿名身份驗證正在獲取舊會話數據。

,所以我增加了一個登出代碼signInAnonymously

mAuth.signOut(); 

,做之前!

感謝大家的幫助!

編輯:我發現了另一種比退出和再次更好的方法(這導致了firebase控制檯上有數百個未使用的匿名用戶,並且因爲該應用程序尚未投入生產,數以百萬計)。

這是我做過什麼:

if (mAuth.getCurrentUser() != null) 
     { 
      mAuth.getCurrentUser().reload(); 
     } 
     else 
     { 
      mAuth.signInAnonymously() 
        .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() 
        { 
         @Override 
         public void onComplete(@NonNull Task<AuthResult> task) 
         { 
          Log.d("FirebaseAuth", "signInAnonymously: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("FirebaseAuth", "signInAnonymously", task.getException()); 
           Toast.makeText(MainActivity.this, "Authentication failed.", 
             Toast.LENGTH_SHORT).show(); 
          } 
          // ... 
         } 
        }); 
     } 

這只是重新加載當前認證(匿名)用戶。

0

您可能需要檢查您的規則以存儲在Firebase控制檯中。默認情況下,它被設置爲僅允許認證的用戶僅 這樣

allow read, write: if request.auth != null; 
+0

的聽起來很公平,但對於3點你的答案的問題: 1)不是匿名身份驗證有效的請求。權威性? (因爲我跑了一個'mAuth.signInAnonymously()'命令) 2)爲什麼它起初工作? 3)什麼應該是規則的代碼?關於我只想通過應用程序訪問存儲,但用戶不在我的應用程序中註冊。 –

+0

** 1)**我猜你正在使用令牌進行身份驗證,這是它完美的工作方式。 ** 2)**匿名身份驗證是臨時身份驗證的,所以他們只存在很短的時間** 3)**因爲你只需要改變你的**存儲** **規則**喜歡'允許讀取,寫' –

3

消息「W/NetworkRequest:沒有身份驗證令牌的請求」是用於調試這個問題的關鍵。

此日誌消息表示在當前上下文中,Firebase存儲沒有看到任何登錄。這包括匿名登錄。這意味着沒有授權傳遞給後端,並且唯一的辦法就是允許您將規則設置爲完全公開(公共訪問),這是不推薦的(見下文)。

//this sets completely open access to your data 
allow read, write; 

我會檢查您登錄時使用的代碼,並確保在任何存儲操作完成之前它已成功完成。 如果您確定您的授權碼是正確的,請嘗試resetting data on the device,這樣就不會有保存的狀態來混淆應用程序的授權信息。

+0

你有一個點!我重置了手機上的應用程序數據,並重新開始工作! +1,但我確信這會再次發生,所以我認爲我必須從Firebase取消設備的授權(即使它可能已超時),然後我可以嘗試打開新會話。 事情是,這是不明確的Firebase官方文檔,你知道一個方法來做到這一點? –

0

有時從火力數據庫的斷開,所以您的應用程序通過火力援助工具在Android Studio中火力身份驗證連接。