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

iOS应用如何从Firebase获取用户专属数据并解决权限、数据拉取异常问题

问题根因与解决方案

两个问题分别由安全规则配置错误、iOS端查询逻辑不匹配两个原因导致,具体修复方案如下:

1. 新增数据权限不足问题修复

根因

你当前的安全规则写法是match /contacts/{creatorsID},要求contacts集合下的文档ID必须等于登录用户的UID,但你iOS端新增数据用的是addDocument()方法,该方法会自动生成随机字符串作为文档ID,和当前用户UID不匹配,直接触发权限校验失败。
另外你的业务逻辑是单个用户可以添加多个联系人,原有规则限制了一个用户只能在contacts下有一个文档,完全不符合业务需求。

安全规则修正

将安全规则调整为匹配contacts下所有文档,区分读写场景做校验,既保证权限安全,也符合单用户多联系人的业务需求:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /contacts/{contactDocId} {
      // 读操作:校验文档所属creatorsID为当前登录用户
      allow read: if request.auth != null && resource.data.creatorsID == request.auth.uid;
      // 新建操作:校验写入的creatorsID为当前登录用户,防止越权创建他人数据
      allow create: if request.auth != null && request.resource.data.creatorsID == request.auth.uid;
      // 修改/删除操作:校验原文档所属creatorsID为当前登录用户
      allow update, delete: if request.auth != null && resource.data.creatorsID == request.auth.uid;
    }
  }
}

2. 拉取到所有用户联系人问题修复

根因

Firebase安全规则不会自动对查询结果做过滤,只会直接拒绝不符合规则的查询。你当前的拉取代码直接监听整个contacts集合,没有加过滤条件,会直接返回所有有权限访问的文档,不符合只拉取当前用户数据的需求。

iOS拉取代码修正

给查询添加whereField过滤条件,只拉取creatorsID等于当前登录用户UID的文档:

func fetchData() {
    // 先校验当前用户已登录
    guard let currentUid = Auth.auth().currentUser?.uid else {
        print("用户未登录")
        return
    }
    // 添加过滤条件,只拉取当前用户创建的联系人
    db.collection("contacts")
        .whereField("creatorsID", isEqualTo: currentUid)
        .addSnapshotListener { (querySnapshot, error) in
        guard let documents = querySnapshot?.documents else {
            print("No documents: \(error?.localizedDescription ?? "未知错误")")
            return
        }

        self.contacts = documents.map { (queryDocumentSnapshot) -> Contact in
            let data = queryDocumentSnapshot.data()
            let name = data["name"] as? String ?? ""
            return Contact(name: name)
        }
    }
}

3. 可选:新增代码优化

可以在新增数据前先校验用户登录状态,避免隐式的nil值写入:

func addData(name: String) {
    guard let currentUid = Auth.auth().currentUser?.uid else {
        print("用户未登录,无法添加数据")
        return
    }
    do {
        _ = try db.collection("contacts").addDocument(data: ["name": name, "creatorsID": currentUid])
    }
    catch {
        print(error.localizedDescription)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 02:24:02