You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firebase实时数据库权限配置与用户误删后评论报错问题求助

Firebase 相关问题解决方案

Hey there, let's tackle your two Firebase-related issues one by one!

1. 修复数据库规则语法错误并实现特定节点写入权限限制

First off, your provided database rules have a few syntax issues that are causing errors:

  • You've duplicated the top-level "rules" node (JSON doesn't allow duplicate keys in the same object)
  • You used && (an HTML escaped character) instead of the valid JSON logical operator &&
  • The .write rule for the "comments" node is missing a trailing semicolon

Here's the corrected rule set that achieves your goal: restricting write access to the comments node for logged-in users who have a valid record in the Users node, plus adding protection to prevent accidental deletion of user records:

{
  "rules": {
    ".read": "auth != null",
    "comments": {
      ".write": "auth != null && root.child('Users').hasChild(auth.uid)",
      ".read": "auth != null"
    },
    "Users": {
      "$uid": {
        ".write": "auth != null && auth.uid === $uid",
        ".read": "auth != null"
      }
    }
  }
}

Rule breakdown:

  • The top-level .read ensures all data is only accessible to logged-in users
  • The comments node's .write rule restricts comment creation to users who are logged in and have an existing record in the Users node
  • The Users node's $uid rule ensures users can only modify their own records, preventing accidental deletion of any user's data (yours or others')

2. 解决用户记录被误删后评论报错的问题

The error you're seeing happens because when a user's record is deleted from the Users node, dataSnapshot.getValue(User.class) returns null, triggering your error handling logic. This issue can't be fixed with User class setters/getters—the problem is missing data, not broken property access. Here are a few practical solutions:

Option 1: Cache user data locally

After a user logs in, cache their User object locally (using SharedPreferences or a global ViewModel). When loading comments, prioritize this cached data instead of fetching from the database every time:

// First, try to get the cached user
User cachedUser = getCachedUser(); // Implement this method to read from SharedPreferences
if (cachedUser != null) {
  proceedWithComment(cachedUser);
} else {
  // Fall back to database fetch if cache is empty
  DatabaseReference userRef = FirebaseDatabase.getInstance().getReference("Users").child(userId);
  userRef.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
      User user = dataSnapshot.getValue(User.class);
      if (user == null) {
        // Fetch basic info from Firebase Auth if database record is missing
        FirebaseUser authUser = FirebaseAuth.getInstance().getCurrentUser();
        if (authUser != null) {
          String username = authUser.getDisplayName() != null ? authUser.getDisplayName() : "Unknown User";
          user = new User(username, authUser.getEmail());
          // Auto-restore the user record in the database
          userRef.setValue(user);
          Log.d(TAG, "Restored missing user record for " + userId);
        } else {
          Log.e(TAG, "User " + userId + " is unexpectedly null and not authenticated");
          Toast.makeText(CommentActivity.this, "Error: could not fetch user.", Toast.LENGTH_SHORT).show();
          return;
        }
      }
      // Cache the user data for next time
      cacheUser(user); // Implement this method to save to SharedPreferences
      proceedWithComment(user);
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
      Log.e(TAG, "Failed to fetch user", databaseError.toException());
      Toast.makeText(CommentActivity.this, "Error: could not fetch user.", Toast.LENGTH_SHORT).show();
    }
  });
}

Option 2: Fall back to Firebase Auth data

When the database user record is missing, pull basic user information directly from Firebase Auth to create a temporary User object, and optionally auto-restore the record in the database:

@Override
public void onDataChange(DataSnapshot dataSnapshot) {
  User user = dataSnapshot.getValue(User.class);
  if (user == null) {
    FirebaseUser authUser = FirebaseAuth.getInstance().getCurrentUser();
    if (authUser != null) {
      // Create a temporary user with Auth data
      String username = authUser.getDisplayName() != null ? authUser.getDisplayName() : "User_" + authUser.getUid().substring(0,6);
      user = new User(username, authUser.getEmail());
      // Restore the user record in the database
      FirebaseDatabase.getInstance().getReference("Users").child(userId).setValue(user);
    } else {
      Log.e(TAG, "User " + userId + " is unexpectedly null and not authenticated");
      Toast.makeText(CommentActivity.this, "Error: could not fetch user.", Toast.LENGTH_SHORT).show();
      return;
    }
  }
  // Continue with comment logic
  // ...
}

Option 3: Prevent user record deletion entirely

Add a rule to the Users node to block deletion of user records, eliminating the problem at its source:

"Users": {
  "$uid": {
    ".write": "auth != null && auth.uid === $uid && newData.exists()", // Block deletion
    ".read": "auth != null"
  }
}

内容的提问来源于stack exchange,提问作者Theo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:03:52