Firebase获取用户分类异常:空结果及Codable解码失败问题
问题:Firebase获取用户分类数据为空/解码失败
我正在开发一款以Firebase为数据库的应用,尝试获取用户的分类数据。Firebase控制台显示用户注册时默认添加了3个分类,但调用接口始终返回空结果。我试过调试,还把调用代码移到.onAppear方法里,都没解决问题。
Firebase控制台截图:
初始代码实现
Firebase Manager类中获取分类的代码
func fetchCategories(forUserId userId: String, completion: @escaping (Result<[Category], Error>) -> Void) { let categoriesRef = db.collection("users").document(userId).collection("categories") print("user id: \(userId)") categoriesRef.getDocuments { (snapshot, error) in if let error = error { completion(.failure(error)) return } guard let documents = snapshot?.documents else { completion(.failure(FirestoreErrorCode.notFound as! Error)) return } let categories = documents.compactMap { document -> Category? in do { return try document.data(as: Category.self) } catch { print("Error decoding category: \(error)") return nil } } completion(.success(categories)) } }
调用代码
.onAppear { FirebaseManager().fetchCategories(forUserId: Auth.auth().currentUser?.uid ?? "") { result in do { let categories = try result.get() print("fetched categories") print(categories.isEmpty ? categories : categories[0]) if categories.isEmpty == false { firstCategory = categories[0] } } catch { print("Error fetching categories: \(error.localizedDescription)") } } }
更新1:改用@EnvironmentObject管理分类数据
根据建议,我在FirebaseManager类里实现了categories数组:
private var db = Firestore.firestore() @Published var categories: [Category] = [] init() { if let userID = Auth.auth().currentUser?.uid { fetchCategories(userID: userID) } }
同时修改了获取分类的函数:
func fetchCategories(userID: String) { let docRef = db.collection("categories").document(userID) docRef.getDocument { (document, error) in guard error == nil else { print("error", error?.localizedDescription ?? "") return } if let document = document, document.exists { let data = document.data() if let data = data { print("data", data) self.categories = data["categories"] as? [Category] ?? [] print(self.categories) } } } }
此外,我通过FirebaseManager类的@EnvironmentObject访问categories数组:
@EnvironmentObject var firebaseManager: FirebaseManager var categories: [Category] { var categories = firebaseManager.categories print(categories) return categories }
并且在@main App声明中添加了@StateObject,并将其注入到WindowGroup的首个视图:
WindowGroup { ZStack { if Auth.auth().currentUser != nil { let _ = print("content view triggered when loading app") ContentView() .environmentObject(firebaseManager) .environmentObject(userData) } else { let _ = print("welcome view triggered when loading app") WelcomeScreen() .environment(firebaseManager) .environmentObject(userData) } } }
但问题仍未解决...
更新2:数据获取成功,但解码失败
我已成功从Firebase获取到数据,但现在无法将数据解码为Category类型。
修改后的获取函数:
func fetchCategories(userID: String) { let docRef = db.collection("users").document(userID) docRef.getDocument { (document, error) in guard error == nil else { print("error", error?.localizedDescription ?? "") return } if let document = document, document.exists { let data = document.data() if let data = data { print("data", data) //self.categories = data["categories"] as? [Category] ?? [] self.categories.append(contentsOf: data["categories"] as? [Category] ?? [Category(title: "Category", emoji: "📚", items: [ Item(title: "ToDo Nr.1", emoji: "📚", priority: .high) ])]) } } else { print("no document exists") } } }
我已为Category类型实现了Codable协议,但不确定如何应用到Firebase返回的数据:
func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(id, forKey: .id) try container.encode(title, forKey: .title) try container.encode(emoji, forKey: .emoji) try container.encode(items, forKey: .items) } required init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) id = try container.decodeIfPresent(String.self, forKey: .id) title = try container.decode(String.self, forKey: .title) emoji = try container.decode(String.self, forKey: .emoji) items = try container.decode([Item].self, forKey: .items) }
内容的提问来源于stack exchange,提问作者not_a_nerd
相关产品推荐
相关产品推荐

