【问题标题】:Firebase suddenly stopped working, using Anonymous AuthFirebase 突然停止工作,使用匿名身份验证
【发布时间】:2016-10-14 12:06:19
【问题描述】:

我已经为我的应用设置了 firebase 存储,并在应用和 firebase 控制台上添加了匿名身份验证代码。

一开始可以,但是不知道为什么停止了,说用户没有访问对象的权限

匿名身份验证已正确设置,我确实看到它工作正常,代码几乎就像 Google Firebase 文档

日志猫:

D/FirebaseAuth:signInAnonymously:onComplete:true
D/Firebase 身份验证: onAuthStateChanged:signed_in: (随机认证用户 id)

...当我从 firebase 请求项目时

E/StorageUtil:获取令牌时出错 java.util.concurrent.ExecutionException:com.google.firebase.FirebaseException:发生内部错误。 [遇到内部错误。] I/DpmTcmClient:RegisterTcmMonitor 来自:com.android.okhttp.TcmIdleTimerMonitor W/NetworkRequest:无身份验证 请求 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;
    }

【问题讨论】:

  • 显示存储的安全规则和重现问题的最少代码(流程在这里相当重要)。
  • 帖子已编辑以添加您要求的内容
  • 不幸的是,该代码没有显示您如何确保在上传图像之前对用户进行身份验证。在开始实际上传之前,您可能需要添加一个简单的检查 if (FirebaseAuth.getInstance().getCurrentUser !0 null)
  • 因为我正在使用匿名身份验证,并且我看到身份验证“成功”,我认为这实际上是不必要的,无论如何感谢确保用户通过身份验证的代码,但是因为我之前作为答案发布(由于我必须等待一天,所以没有接受它是正确的)解决方案是退出当前经过身份验证的“用户”

标签: android firebase firebase-storage


【解决方案1】:

正如 Benjamin Wulfe 所暗示的那样,我删除了手机上的应用程序数据并且它起作用了,这意味着手机上存储了某种 Token 数据,而 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();
                            }
                            // ...
                        }
                    });
        }

这只是重新加载当前经过身份验证的(匿名)用户。

【讨论】:

  • 我也面临同样的问题,这个解决方案解决了这个问题。但在我的情况下,我使用了 signinwithemailandpassword 方法
【解决方案2】:

消息“W/NetworkRequest: no auth token for request”是调试此问题的关键。

此日志消息表示 Firebase 存储在当前上下文中没有看到 任何 登录。这包括匿名登录。这意味着没有将授权传递给后端,唯一允许这样做的方法是,如果您将规则设置为完全开放(公共访问),不建议这样做(见下文)。

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

我会检查您用于登录的代码,并确保它在任何存储操作完成之前成功完成。 如果您确定您的授权码是正确的,请尝试resetting data on the device,这样就可能没有保存的状态来弄乱应用程序的授权信息。

【讨论】:

  • 你说得有道理!我在手机上重置了应用程序的数据,它又开始工作了! +1,但我确信这会再次发生,所以我认为我必须先从 Firebase 取消对设备的身份验证(即使它可能已经超时),然后才能尝试打开新会话。问题是这在 Firebase 官方文档中并不清楚,你知道一种方法吗?
【解决方案3】:

您可能需要检查您的 RULES 以在 Firebase 控制台中进行存储。默认情况下,它设置为仅允许经过身份验证的用户 像这样

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

【讨论】:

  • 听起来很公平,但是关于您的回答有 3 个问题:1) 匿名身份验证对 request.auth 无效吗? (因为我正在运行 'mAuth.signInAnonymously()' 命令) 2) 为什么它一开始有效? 3)规则的代码应该是什么?关于我只想通过应用程序访问存储,但用户不会在我的应用程序中注册。
  • 1) 我猜你正在使用令牌进行身份验证,这就是它完美工作的方式。 2) 匿名身份验证是临时身份验证,所以它们只存在很短的时间 3) 因为你只需要更改你的 存储 规则点赞allow read, write
【解决方案4】:

有时它会与 firebase 数据库断开连接,因此通过 firebase 辅助工具在 android studio 中将您的应用与 firebase 身份验证连接起来。

【讨论】:

    猜你喜欢
    • 2017-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-15
    • 2020-10-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多