每当我尝试从数据库中读取(我可以写)时,都会被拒绝权限
/* Visit https://firebase.google.com/docs/database/security to learn more about security rules. */
"rules": {
"Users": {
"$user_id":{
".read": "$user_id == auth.uid",
".write": "$user_id == auth.uid"
}
}
}
}
这是应该检索数据库中每个用户的活动(我有20个)
import android.content.Context;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.example.shrinkio.Adapter.UserAdapter;
import com.example.shrinkio.R;
import com.example.shrinkio.model.User;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.List;
public class PeopleFragment extends Fragment {
private RecyclerView recyclerView;
private UserAdapter userAdapter;
private List<User> mUsers;
EditText search_bar;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_people, container, false);
recyclerView = view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
search_bar = view.findViewById(R.id.search_bar);
mUsers = new ArrayList<>();
userAdapter = new UserAdapter(getContext(), mUsers);
recyclerView.setAdapter(userAdapter);
readUsers();
search_bar.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
searchUsers(charSequence.toString().toLowerCase());
}
@Override
public void afterTextChanged(Editable editable) {
}
});
return view;
}
private void searchUsers(String s) {
Query query = FirebaseDatabase.getInstance().getReference("Users").child("user_Id").orderByChild("Name").startAt(s).endAt(s+"\uf8ff");
query.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
mUsers.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
User user = snapshot.getValue(User.class);
mUsers.add(user);
}
userAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
public void readUsers(){
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Users");
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if ( search_bar.getText().toString().equals("")) {
mUsers.clear();
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()){
User user = dataSnapshot.getValue(User.class);
mUsers.add(user);
}
} }
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
}
如前所述,在回收者视图中,我应该获得20个用户,但是,没有错误发生,但是活动仍然为空白,一旦我检查了logcat,就会遇到以下错误。
它确实显示为错误,但是我看不到数据库上的帖子或任何用户信息:
W/SyncTree: Listen at /Users failed: DatabaseError: Permission denied
答案 0 :(得分:0)
您的安全规则要求用户必须先登录,然后才能读取/写入数据库。即使这样,用户也只能在/Users/theirUid
下读取或写入自己的节点,其中theirUid
是Firebase Authentication首次登录时为其分配的用户ID。
您的代码完全不使用Firebase身份验证。这意味着没有用户登录,因此/Users
上的读取操作被拒绝。
您需要进行两项更改:
/Users
,或者将代码缩小为仅读取/Users/theirUid
。后者实质上使搜索变得不可能。如果要允许用户搜索数据,而不是读取所有数据,请考虑在Cloud Functions中实现搜索功能。由于Cloud Functions在受信任的环境中运行,因此它们具有对数据库中数据的完全访问权限。但是,由于您的代码在服务器上运行,因此可以确保用户只能访问您的代码所允许的内容。
答案 1 :(得分:0)
如果您希望能够搜索用户,则需要在/Users
级别授予读取访问权限。但是由于实时数据库中的security rules cascade,如果您授予了这样的权限,则更深层次的限制性“ .read”规则将被忽略,从而允许任何用户读取私有用户数据。
"rules": {
"Users": {
"$user_id": {
".read": "$user_id == auth.uid", // ignored, superseded by /Users/.read rule
".write": "$user_id == auth.uid"
},
".read": "auth != null" // logged in users can read everything under /Users
}
}
相反,我建议将用户数据分为私人用户数据和公共档案数据。公开个人资料将包含非敏感信息,例如显示名称,个人资料图片,用户名,哈希电子邮件地址(用于“通过电子邮件搜索” / Gravatar)等。
"rules": {
"Users": {
"$user_id": {
".read": "$user_id == auth.uid", // only the owner can read/write their private data
".write": "$user_id == auth.uid"
}
},
"Profiles": {
"$user_id": {
".write": "$user_id == auth.uid" // only the profile owner can update their profile
},
".read": "auth != null" // logged in users can read everything under /Profiles
}
}
在前端,您可以将RecyclerView更改为使用/Profiles
。