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

Swift实现Firestore仅添加未存在收藏商品问题求助

解决Firestore收藏重复添加商品的问题

核心问题分析

你的isProductInFavorites方法完全失效,原因有两个:

  1. 异步操作同步返回:Firestore的getDocument是异步方法,你直接返回初始值false,等异步请求拿到结果时,方法早就返回了,判断逻辑根本没生效。
  2. 查询逻辑错误:你现在查询的是Favorite集合中以商品ID命名的文档是否存在,但正常的收藏结构应该是一个用户对应一个Favorite文档,文档内存储该用户的所有收藏商品ID/对象,而不是每个商品单独建文档。

分步解决方案

1. 修正收藏存在性判断的异步逻辑

用Swift的async/await重构判断方法,同时修正查询逻辑,检查当前用户的收藏文档里是否包含目标商品:

func isProductInFavorites(product: Product) async -> Bool {
    guard let userId = "123" else { return false } // 替换为当前登录用户的真实ID,比如Auth.auth().currentUser?.uid
    let db = Firestore.firestore()
    
    // 假设用户的收藏文档ID是favoriteListener.favorite?.id 或者用户ID
    let targetDocRef = db.collection("Favorite").document(favoriteListener.favorite?.id ?? userId)
    
    do {
        let document = try await targetDocRef.getDocument()
        guard let favoriteData = document.data() else { return false }
        
        // 假设你的Favorite结构体用productIds数组存储商品ID,根据实际结构调整
        if let collectedProductIds = favoriteData["productIds"] as? [String] {
            return collectedProductIds.contains(product.id)
        }
        // 如果是直接存储Product对象数组,用下面的判断
        // if let collectedProducts = favoriteData["products"] as? [[String: Any]] {
        //     return collectedProducts.contains { $0["id"] as? String == product.id }
        // }
        return false
    } catch {
        print("查询收藏状态失败: \(error.localizedDescription)")
        return false
    }
}

2. 重构添加收藏的异步逻辑

把addItemToFavorites改成异步方法,等待判断结果后再执行添加操作,同时只有真的添加新商品时才更新Firestore:

// 新增@State变量存储提示文本
@State private var alertMessage = "Adăugat la preferate."

private func addItemToFavorites() async {
    var favorite: Favorite!
    
    if let existingFavorite = favoriteListener.favorite {
        let isAlreadyCollected = await isProductInFavorites(product: product)
        if isAlreadyCollected {
            alertMessage = "Produsul este deja în preferate."
        } else {
            favorite = existingFavorite
            favorite.add(product)
            await favorite.saveFavoritesToFirestore()
        }
    } else {
        // 首次创建收藏文档
        favorite = Favorite()
        favorite.ownerId = "123" // 替换为真实用户ID
        favorite.id = UUID().uuidString
        favorite.add(product)
        await favorite.saveFavoritesToFirestore()
    }
    
    // 最后统一弹出提示
    showAlert = true
}

3. 修改按钮点击事件的异步调用

在SwiftUI中触发异步任务需要用Task包裹,避免阻塞UI:

Button {
    Task {
        await addItemToFavorites()
    }
} label: {
    Image(systemName: "heart")
        .font(.title3)
        .frame(height: 50)
        .frame(maxWidth: 50)
        .background(self.complementColor)
        .foregroundColor(self.averageColor)
        .cornerRadius(25)
}
.alert(isPresented: $showAlert) {
    Alert(title: Text(alertMessage), dismissButton: .default(Text("OK")))
}

额外优化建议

  • 实时同步收藏状态:利用favoriteListener的监听功能,在视图初始化时就拉取当前用户的收藏数据,之后直接在本地判断商品是否已收藏,不用每次都请求Firestore,既提升响应速度又减少请求次数。
  • Firestore文档结构优化:确保Favorite文档内用商品ID数组存储收藏记录,比存储完整Product对象更节省空间,查询和判断也更高效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 07:15:26