Swift实现Firestore仅添加未存在收藏商品问题求助
解决Firestore收藏重复添加商品的问题
核心问题分析
你的isProductInFavorites方法完全失效,原因有两个:
- 异步操作同步返回:Firestore的
getDocument是异步方法,你直接返回初始值false,等异步请求拿到结果时,方法早就返回了,判断逻辑根本没生效。 - 查询逻辑错误:你现在查询的是
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
相关产品推荐
相关产品推荐

