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

SwiftUI Firebase聊天应用删除会话后对方打开崩溃问题求助

问题分析与解决方案

问题根源

当用户删除自己的聊天会话时,原删除逻辑仅从Thread文档的uid数组移除了自身ID,但未正确判断是否需要删除整个文档(deleteThreadIfNecessary传入的是移除前的Thread对象,导致判断失效)。此时聊天伙伴的客户端会收到一个uid数组仅包含自身ID的Thread,计算chatPartnerId时返回空字符串,调用fetchUser时传入空ID触发Firebase的FIRInvalidArgumentException错误。

修复步骤

1. 修正删除逻辑,确保无效Thread被彻底清理

修改删除流程,移除用户ID后获取最新的Thread数据,再判断是否需要删除文档:

func deleteThread(_ thread: Thread) async throws {
    guard let uid = Auth.auth().currentUser?.uid else { return }
    // 移除当前用户ID
    try await removeUserFromThread(thread, uid: uid)
    // 获取更新后的Thread文档
    let updatedThreadDoc = try await THREADS.document(thread.id).getDocument()
    guard var updatedThread = try? updatedThreadDoc.data(as: Thread.self) else { return }
    // 当无参与者或只剩当前用户时删除文档
    try await deleteThreadIfNecessary(updatedThread)
}

private func deleteThreadIfNecessary(_ thread: Thread) async throws {
    guard let currentUid = Auth.auth().currentUser?.uid else { return }
    let shouldDelete = thread.uid.isEmpty || (thread.uid.count == 1 && thread.uid.first == currentUid)
    if shouldDelete {
        try await THREADS.document(thread.id).delete()
    }
}

2. 添加入口校验,避免无效Thread进入会话列表

在createNewThread方法中先检查chatPartnerId是否有效,为空则跳过插入:

func createNewThread(_ thread: Thread) async {
    guard !thread.chatPartnerId.isEmpty else {
        print("DEBUG: 无效会话,无聊天伙伴,跳过插入")
        return
    }
    do {
        var copy = thread
        copy.chatPartner = try await UserService().fetchUser(withUid: thread.chatPartnerId)
        self.threads.insert(copy, at: 0)
    } catch {
        print("DEBUG: 获取聊天伙伴失败,错误:\(error)")
    }
}

3. 增强Thread模型的安全性

优化Thread模型的属性计算,添加有效性校验:

struct Thread: Identifiable, Hashable, Codable {
    // ... 原有属性 ...
    
    var chatPartnerId: String {
        guard let currentUid = Auth.auth().currentUser?.uid else { return "" }
        return uid.filter { $0 != currentUid }.first ?? ""
    }
    
    // 新增:判断是否有有效聊天伙伴
    var hasValidChatPartner: Bool {
        return !chatPartnerId.isEmpty
    }
}

之后可以用thread.hasValidChatPartner替代直接判断字符串是否为空,代码可读性更强。

4. 过滤流式获取的无效Thread

在streamThreads中提前过滤掉无有效聊天伙伴的Thread,避免后续处理出错:

func streamThreads() async {
    for await thread in service.streamThreads() {
        guard thread.hasValidChatPartner else {
            // 可选:自动清理Firestore中的无效Thread
            try? await service.deleteThread(thread)
            continue
        }
        await updateThreads(thread)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 20:35:05