Firebase 突然停止工作,使用匿名身份验证
Firebase suddenly stopped working, using Anonymous Auth
我已经为我的应用程序设置了 firebase 存储,并在应用程序和 firebase 控制台上添加了匿名身份验证代码。
一开始是可以的,不知道为什么就停止了,说用户没有访问该对象的权限
匿名身份验证设置正确,我确实看到它在工作,代码几乎像 Google Firebase 文档
logcat:
D/FirebaseAuth: signInAnonymously:onComplete:true
D/FirebaseAuth:
onAuthStateChanged:signed_in: (Random auth user id)
...当我从 firebase 请求该项目时
E/StorageUtil: error getting token java.util.concurrent.ExecutionException: com.google.firebase.FirebaseException: An internal error has occured. [Internal error encountered.]
I/DpmTcmClient: RegisterTcmMonitor
from: com.android.okhttp.TcmIdleTimerMonitor W/NetworkRequest: no auth
token for request E/StorageException: StorageException has occurred.
User does not have permission to access this object.
Code: -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;
}
您可能需要检查您的 RULES 以便在 Firebase 控制台中存储。默认情况下,它设置为仅允许经过身份验证的用户
像这样
allow read, write: if request.auth != null;
消息“W/NetworkRequest:请求没有授权令牌”是调试此问题的关键。
此日志消息表示 Firebase 存储在当前上下文中未看到 任何 登录。这包括匿名登录。这意味着没有授权被传递到后端,唯一允许的方法是将规则设置为完全开放(public 访问),这是不推荐的(见下文)。
//this sets completely open access to your data
allow read, write;
我会检查您的登录代码并确保它在任何存储操作完成之前成功完成。
如果您确定您的授权代码是正确的,请尝试 resetting data on the device 这样就没有保存的状态可能会弄乱应用程序的授权信息。
正如 Benjamin Wulfe 所暗示的,我删除了应用程序在 phone 上的数据并且它起作用了,这意味着某种令牌数据存储在 phone 上并且 Anonymous Auth 正在变老会话数据。
所以我在 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();
}
// ...
}
});
}
这只会重新加载当前经过身份验证的(匿名)用户。
有时它会与 firebase 数据库断开连接,因此请通过 firebase 辅助工具在 android studio 中将您的应用程序与 firebase 身份验证连接起来。
我已经为我的应用程序设置了 firebase 存储,并在应用程序和 firebase 控制台上添加了匿名身份验证代码。
一开始是可以的,不知道为什么就停止了,说用户没有访问该对象的权限
匿名身份验证设置正确,我确实看到它在工作,代码几乎像 Google Firebase 文档
logcat:
D/FirebaseAuth: signInAnonymously:onComplete:true
D/FirebaseAuth: onAuthStateChanged:signed_in: (Random auth user id)
...当我从 firebase 请求该项目时
E/StorageUtil: error getting token java.util.concurrent.ExecutionException: com.google.firebase.FirebaseException: An internal error has occured. [Internal error encountered.] I/DpmTcmClient: RegisterTcmMonitor from: com.android.okhttp.TcmIdleTimerMonitor W/NetworkRequest: no auth token for request E/StorageException: StorageException has occurred. User does not have permission to access this object. Code: -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;
}
您可能需要检查您的 RULES 以便在 Firebase 控制台中存储。默认情况下,它设置为仅允许经过身份验证的用户 像这样
allow read, write: if request.auth != null;
消息“W/NetworkRequest:请求没有授权令牌”是调试此问题的关键。
此日志消息表示 Firebase 存储在当前上下文中未看到 任何 登录。这包括匿名登录。这意味着没有授权被传递到后端,唯一允许的方法是将规则设置为完全开放(public 访问),这是不推荐的(见下文)。
//this sets completely open access to your data
allow read, write;
我会检查您的登录代码并确保它在任何存储操作完成之前成功完成。 如果您确定您的授权代码是正确的,请尝试 resetting data on the device 这样就没有保存的状态可能会弄乱应用程序的授权信息。
正如 Benjamin Wulfe 所暗示的,我删除了应用程序在 phone 上的数据并且它起作用了,这意味着某种令牌数据存储在 phone 上并且 Anonymous Auth 正在变老会话数据。
所以我在 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();
}
// ...
}
});
}
这只会重新加载当前经过身份验证的(匿名)用户。
有时它会与 firebase 数据库断开连接,因此请通过 firebase 辅助工具在 android studio 中将您的应用程序与 firebase 身份验证连接起来。