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

Android Firebase基于用户的安全实现:用户仅查看自身维护记录问题

嘿,这个问题太常见了——核心就是没给维护数据加上用户UID的隔离逻辑,咱们一步步把它搞定:

第一步:先调整你的Firebase数据库结构

首先得确保每条维护记录都和用户的UID绑定,推荐两种结构选其一:

  • 结构一(适合后续跨用户统计):
maintenanceRecords
  - [随机生成的recordId]
    - uid: "当前登录用户的Firebase UID"
    - title: "维护标题"
    - content: "维护详情"
    - createTime: 1698765432 // 时间戳
    ...其他字段
  • 结构二(查询更直接):
userMaintenanceRecords
  - [用户UID]
    - [随机生成的recordId]
      - title: "维护标题"
      - content: "维护详情"
      ...其他字段
第二步:在MaintenanceActivity中做UID过滤查询

你之前的查询是拉取了所有记录,现在要加上仅匹配当前用户UID的过滤条件,分两种数据库类型给你示例:

如果你用的是Realtime Database

// 先获取当前登录用户的UID
FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser();
if (currentUser != null) {
    String currentUid = currentUser.getUid();
    // 指向维护记录的数据库节点
    DatabaseReference recordsRef = FirebaseDatabase.getInstance().getReference("maintenanceRecords");
    // 关键:添加过滤条件,只拉取uid等于当前用户UID的记录
    Query userSpecificRecords = recordsRef.orderByChild("uid").equalTo(currentUid);
    
    // 监听查询结果并更新UI
    userSpecificRecords.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            // 先清空旧列表,再添加当前用户的记录
            maintenanceRecordList.clear();
            for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                MaintenanceRecord record = snapshot.getValue(MaintenanceRecord.class);
                maintenanceRecordList.add(record);
            }
            yourRecordAdapter.notifyDataSetChanged();
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.e("MaintenanceActivity", "查询失败: " + databaseError.getMessage());
        }
    });
}

如果你用的是Firestore

FirebaseFirestore db = FirebaseFirestore.getInstance();
String currentUid = FirebaseAuth.getInstance().getCurrentUser().getUid();
// 关键:添加whereEqualTo条件过滤UID
db.collection("maintenanceRecords")
    .whereEqualTo("uid", currentUid)
    .addSnapshotListener(new EventListener<QuerySnapshot>() {
        @Override
        public void onEvent(@Nullable QuerySnapshot value, @Nullable FirebaseFirestoreException e) {
            if (e != null) {
                Log.w("MaintenanceActivity", "监听失败", e);
                return;
            }
            // 更新列表和适配器
            maintenanceRecordList.clear();
            for (QueryDocumentSnapshot doc : value) {
                MaintenanceRecord record = doc.toObject(MaintenanceRecord.class);
                maintenanceRecordList.add(record);
            }
            yourRecordAdapter.notifyDataSetChanged();
        }
    });
第三步:设置Firebase安全规则(重中之重!)

光在代码里过滤还不够,必须通过安全规则防止恶意用户绕开App直接访问他人数据:

Realtime Database规则

{
  "rules": {
    "maintenanceRecords": {
      ".read": "auth != null && auth.uid == data.child('uid').val()",
      ".write": "auth != null && auth.uid == newData.child('uid').val()"
    }
  }
}

解释:只有登录用户,且要操作的记录UID和当前用户UID一致,才能读/写数据。

Firestore规则

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /maintenanceRecords/{record} {
      allow read, write: if request.auth != null && request.auth.uid == resource.data.uid;
    }
  }
}
第四步:新增记录时记得绑定UID

别忘在用户提交新维护记录的时候,把当前用户的UID一起存进去:

// 示例:创建新记录并绑定UID
MaintenanceRecord newRecord = new MaintenanceRecord();
newRecord.setTitle("设备保养");
newRecord.setContent("更换空气滤芯");
newRecord.setUid(FirebaseAuth.getInstance().getCurrentUser().getUid()); // 关键!

// Realtime Database写法
recordsRef.push().setValue(newRecord);
// Firestore写法
db.collection("maintenanceRecords").add(newRecord);

最后补个小提醒:在MaintenanceActivity启动时,最好先判断用户是否登录,如果未登录直接跳回LoginActivity,避免空指针问题~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:08:00