如何确保用户只能在 firebase 中查看和访问自己的数据?

How to make sure a user can only see and access their own data in firebase?

我是 Firebase 的新手。在我的 Android 应用程序中,我希望每个用户只能访问他创建的数据。我正在阅读 https://www.firebase.com/docs/security/guide/securing-data.html,但没有多大意义。假设我已经使用电子邮件和密码登录,

  1. 我该如何编写 Firebase 规则?
  2. 如何在我的 Android Java 代码中写入我的 Firebase 数据?

谢谢!

Firebase 规则

{
    "rules": {
        ".read": true,
        ".write": true
    }
}

Java代码

myFirebaseRef.child("message").setValue("This is the message");

如果您使用 oauth,这是最基本的示例:

 {
  "rules": {
    "users": {
      "$uid": {
        ".write": "$uid === auth.uid",
        ".read": "$uid === auth.uid"
      }
    }
  }
}

https://www.firebase.com/docs/security/guide/user-security.html 这个 link 应该会有更多帮助。

auth.uid 我认为是当前正在连接的用户,$uid 是用户在系统中的识别方式(在本例中为 firebase)。

我的示例使用 google 登录,但它应该适用于所有其他类型。

我不确定以下内容,但我相信它是这样工作的:

Firebase 在(首次)成功登录时自动生成代表用户的唯一 ID,并且仅执行一次。然后它使用该数据对新请求进行身份验证,如果找到匹配项,则规则 $iud === auth.uid 为真,在我的示例中,用户可以读取和写入。

多亏了 Joey Rosing,我才能够弄清楚其余部分。我需要根据用户的uid对数据进行分组。

首先,按照Joey提到的修改Firstbase规则:

{
  "rules": {
    "users": {
      "$uid": {
        ".write": "$uid === auth.uid",
        ".read": "$uid === auth.uid"
      }
    }
  }
}

然后,在我的Java代码中:

Firebase rootRef = new Firebase("https://user-account.firebaseio.com/");
// Assuming the user is already logged in.
Firebase userRef = rootRef.child("users/" + rootRef.getAuth().getUid());
userRef.child("message1").setValue("Hello World");

最后,我的数据看起来像这样:

您需要 POJO/Custom class 才能高效地 write/read 到 Firebase 数据库。 理想情况下,您已经创建了一个 class Message,其中包含 setter 和 getter 以及定义的默认构造函数:

class Message {
  private String message;

  public Message() {
  }
  public Message(String message) {
    this.message = message;
  }

  public void getMessage() {
    return message;
  }
  public void setMessage(String message) {
    this.message = message;
  }
}

然后将您的规则更改为:

{
 "rules": {
   "message": {
    "$uid": {
      ".write": "$uid === auth.uid",
      ".read": "$uid === auth.uid"
   }
  }
 }
}

然后在您的 java 代码中执行此操作:

DatabaseReference mDatabaseReference;
FirebaseUser firebaseUser;

 mAuthListener = new FirebaseAuth.AuthStateListener() {
        @Override
        public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
            firebaseUser = firebaseAuth.getCurrentUser();
            if (firebaseUser != null) {
                // User is signed in
            } else {
                // User is signed out
            }
        }
    };
...


//To save a message associated to only the signed in user
Message message = new Message();
message.setMessage("a message");
mDatabaseReference = FirebaseDatabase.getInstance().getReference(); 
mDatabaseReference.child("message").child(firebaseUser.getUid())
     .setValue(message)
     .addOnCompleteListener(DetailsCaptureActivity.this, new OnCompleteListener<Void>() {
     ...
  });

现在,要读取此数据,请执行以下操作:

//Set up an AuthStateListener that responds to changes in the user's sign-in state:
    mAuthListener = new FirebaseAuth.AuthStateListener() {
        @Override
        public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
            firebaseUser = firebaseAuth.getCurrentUser();
            if (firebaseUser != null) {

                   databaseReference = firebaseDatabase.getReference().child("message").child(firebaseUser.getUid());
                   databaseReference.addValueEventListener(new ValueEventListener() {
                      @Override
                      public void onDataChange(DataSnapshot dataSnapshot) {
                          Message message = dataSnapshot.getValue(Message.class);
                          //You can now get your message using message.getMessage();
                      }

                      @Override
                      public void onCancelled(DatabaseError databaseError) {

                          Log.e(TAG, databaseError.getMessage());
                      }
                  });

            } else {
                Log.e(TAG, "onAuthStateChanged:signed_out");
            }
        }
    };

就这些了。

您现在可以添加自己的实现来检索 messages.Hopefully 的列表,这不是问题。