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

Firebase iOS SDK:getDocuments()调用阻塞函数执行陷入停滞

Firebase Firestore异步查询getDocuments()停滞无返回

问题描述

我编写了一个异步函数getStoredUser(),用于在Firebase的users集合中查询id等于userId的文档,若该文档不存在则创建新文档。该函数不在main线程中执行,但调用query.getDocuments()时,函数整体执行停滞,无法返回结果。断点停在getDocuments()所在行,后续代码未执行,预期返回StoredUser实例或nil,但无任何返回。相关Swift代码如下:

func getStoredUser() async throws -> StoredUser? {
        print("UserRepository: Get Stored User")
        let query = usersReference
            .whereField("id", isEqualTo: userId)
        do {
        let querySnapshot = try await query.getDocuments() // <------- 断点停滞处
        print(querySnapshot)
            
        if let first = querySnapshot.documents.first {
            let document = try first.data(as: StoredUser.self)
            print("There is a document", first)
            return document
        } else {
            print("No document")
            let doc = StoredUser(id: userId, usedBefore: false, achievements: Achievement(), userID: userId)
            print(doc)
            try await createStoredUser(doc)
            return doc
        }
    } catch {
        print("Error fetching stored user:", error)
        throw error
    }
}

可能的原因及解决方案

1. 线程死锁

即便函数不在主线程执行,若调用getStoredUser()的代码存在同步等待异步结果的逻辑(比如使用Task.wait()、DispatchQueue.sync阻塞线程),会导致Firestore内部调度线程被卡死,查询无法继续。

  • 解决:全程使用异步/await模式调用该函数,避免任何阻塞式等待。例如:
    // 正确调用方式
    Task {
        do {
            let user = try await getStoredUser()
            // 处理结果
        } catch {
            // 处理错误
        }
    }
    

2. Firebase配置或权限问题

  • 检查Firebase初始化:确保FirebaseApp.configure()在应用启动阶段(如AppDelegate.application(_:didFinishLaunchingWithOptions:))正确执行,未被遗漏。
  • 检查Firestore安全规则:确认当前用户(或匿名用户)拥有users集合的读取权限。若规则限制未认证用户读取,而当前未登录,查询会静默挂起。可临时开放测试规则排查:
    rules_version = '2';
    service cloud.firestore {
      match /databases/{database}/documents {
        match /users/{document=**} {
          allow read, write: if true; // 仅测试用,上线前需修改为安全规则
        }
      }
    }
    

3. 模型解析隐性问题

虽然断点停在getDocuments(),但也可能是查询已完成,但StoredUser的Codable解析存在未被捕获的异常?可以临时修改代码排查:

  • 在getDocuments()后先打印原始文档数据,确认查询是否实际完成:
    let querySnapshot = try await query.getDocuments()
    print("共获取到 \(querySnapshot.documents.count) 条文档")
    querySnapshot.documents.forEach { print("原始数据: \($0.data())") }
    
  • 验证StoredUser的Codable实现:确保所有字段与Firestore文档的键名完全匹配,没有类型不匹配或必填字段缺失的情况。

4. 网络或服务故障

  • 检查设备网络连接,确保能正常访问互联网。
  • 登录Firebase控制台,确认Firestore服务状态正常,无故障告警。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 19:06:17