Firebase+SwiftUI。无法转换价值

Posted

技术标签:

【中文标题】Firebase+SwiftUI。无法转换价值【英文标题】:Firebase+SwiftUI. Cannot convert value 【发布时间】:2020-06-09 16:26:28 【问题描述】:

当我尝试运行以下代码时,我看到的错误是:

无法转换“任何?”类型的值到预期的参数类型“字符串”

在返回线上。如何解决此错误?此功能正在尝试从文档中获取数据,以便我可以编辑。谢谢!

db.collection("routines").whereField("uid", isEqualTo: currUser?.uid).addSnapshotListener  (querySnapshot, error) in
            guard let documents = querySnapshot?.documents else 
                print("No documents")
                return
            
            self.routines = documents.map  queryDocumentSnapshot -> Routine in
                let data = queryDocumentSnapshot.data()
                let id = data["id"]
                let routine = data["routine"] as? String ?? ""
                return Routine(id: id, routine: routine)
            
        

编辑 将 id 更改为 let id = String(describing: data["id"]!) 以使其工作。很想知道这是否是正确的做法!

根据以下答案进行编辑 尝试了您的建议,但似乎无法使其发挥作用。该视图最终没有显示我的任何例程。

型号

struct Routine: Identifiable, Codable 
   @DocumentID var id: String?
   var routine: String
   var uid: String

   enum CodingKeys: String, CodingKey 
      case id
      case routine
      case uid
   

视图模型

class RoutinesViewModel: ObservableObject 
    @Published var routines = [Routine]()
    var db = Firestore.firestore()
    let currUser = Auth.auth().currentUser

    func fetchData() 
        db.collection("routines").whereField("uid", isEqualTo: currUser?.uid).addSnapshotListener  (querySnapshot, error) in
            guard let documents = querySnapshot?.documents else 
                print("No documents")
                return
            
            self.routines = documents.compactMap  queryDocumentSnapshot -> Routine? in


     return try? queryDocumentSnapshot.data(as: Routine.self)
        

查看

List 
    ForEach(viewModel.routines)  routine in
        HStack 
            Text("\(routine.routine)")
        
    

【问题讨论】:

【参考方案1】:

data() 方法返回一个字典,该字典将String 映射到Any - 有关详细说明,请参阅this video。

查看您的data model,我注意到您在所有文档上都有一个与文档ID 等效的id 字段。这实际上不是必需的,因为您可以直接使用文档 ID:

let id = queryDocumentSnapshot.documentID

但是,我建议使用 Firestore 的 Codable 支持来简化此操作:

let routine = try? queryDocumentSnapshot.data(as: Routine.self)

要完成这项工作,您需要添加FirebaseFirestoreSwift,并将您的模型设为Codable

分别在 SO answer、this 和 this article 中了解更多信息。

【讨论】:

感谢彼得回答我的许多问题!我尝试实现这一点,但似乎无法让视图读取数据。请参阅上面编辑过的问题。 你调用了fetchData函数吗? 是的!这样做就如教程所说的那样出现。 可以分享一下日志输出吗?此外,尝试单步执行视图模型代码,看看它在哪里停止按预期工作。 (即 querSnapshot 是否包含任何文档,映射是否失败等) 嗨@DavidLau - 如果这仍然是一个问题,请提供更多详细信息(例如日志输出,或指向您的 Github 存储库的链接,以便人们仔细查看)。

以上是关于Firebase+SwiftUI。无法转换价值的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 SwiftUI 从 Firebase / Firestore 中删除文档

无法将数据从 Firebase 附加到数组 SwiftUI

SwiftUI:Firebase ForEach 列表执行编辑功能无法编辑选定的行项目

SwiftUI 将数据从 Firebase 加载到 TextView

如何使用 SwiftUI 更新 Firebase 中的集合?

处理 SwiftUI 组合应用程序中的 Firebase 身份验证错误