![](/img/trans.png)
[英]SwiftUI: How to iterate over Documents in Cloud Firestore Collection and get Data?
[英]How Do I Add Dynamic Sub Collection Data In Firestore In SwiftUI?
我是 swift 和 firebase 的新手,正在尝试很多事情。 我在应用程序中显示的 firebase 中创建了一组“字符”。 目的是通过赚取积分来解锁“角色”。 通过步行获得积分(使用 HealthKit 获取步数)
当用户点击一个字符然后点击“解锁”时,它被添加到一个名为 UnlockingCharacters 的结构中。
UnlockingCharacters 显示在用户配置文件中。
我需要在 Firebase 上制作用户文档的 UnlockingCharacters 结构的一部分(也许作为子集合?)
我想将 UnlockingCharacters 中的字符数限制为 2。通过采取变成点的步骤来解锁字符。 当点数上传到 Firebase 时,角色会收到这些点数并将其添加到其总数中(角色点数是所有解锁角色点数的用户的总和)。
下面是人物模型:
struct Character: Identifiable, Decodable {
@DocumentID var id: String?
var character_name: String
var character_type: String
var character_image: String
var character_details: String
var character_usersUnlocking: Int
var character_totalPoints: Int
var user: UserModel?
var didUnlock: Bool? = false
// To identify whether it is being unlocked...
var isUnlocking: Bool = false
}
这是 UnlockingCharacters 模型:
struct UnlockingCharacters: Identifiable {
var id = UUID().uuidString
var character: Character
}
共享数据模型:
class SharedDataModel: ObservableObject {
// Unlocking Characters...
@Published var unlockingCharacters: [Character] = []
}
我的功能:
func isUnlocked() -> Bool {
return sharedData.unlockingCharacters.contains { characterData in
return self.characterData.id == characterData.id
}
}
func addToUnlocking() {
if let index = sharedData.unlockingCharacters.firstIndex(where: {
characterData in
return self.characterData.id == characterData.id
}){
// Remove from unlocking...
sharedData.unlockingCharacters.remove(at: index)
}
else {
// Add to unlocking...
sharedData.unlockingCharacters.append(characterData)
}
}
我知道我的 UserModel 也需要添加一些东西,但是我收到一个错误:
struct UserModel: Identifiable, Decodable {
var username : String
var pic : String
var bio: String
var uid : String
var id: String { uid }
//I am getting error for the following variable:
(Value type 'UserModel' cannot have a stored property that recursively contains it)
var activeUnlockingCharacters: UnlockingCharacters
}
总而言之,我需要将 UnlockingCharacters 添加到 Firebase 上的用户文档中。
我在处理自定义对象时遇到错误。 这是我的代码:
let ref = Firestore.firestore()
func fetchUser(uid: String,completion: @escaping (UserModel) -> ()){
let db = Firestore.firestore()
ref.collection("Users").document(uid).getDocument { (doc, err) in
guard let user = doc else{return}
let username = user.data()?["username"] as? String ?? "No Username"
let pic = user.data()?["imageurl"] as? String ?? "No image URL"
let bio = user.data()?["bio"] as? String ?? "No bio"
let uid = user.data()?["uid"] as? String ?? ""
do {
try db.collection("Users").document("\(uid)").setData(from: UnlockingCharacters)
} catch let error {
print("Error writing object to Firestore: \(error)")
}
DispatchQueue.main.async {
completion(UserModel(username: username, pic: pic, bio: bio, uid: uid, activeUnlockingCharacters: UnlockingCharacters))
}
}
}
做的错误是:“类型'UnlockingCharacters.Type'不能符合'Encodable'”
DispatchQueue 中的错误是:“无法将 'UnlockingCharacters.Type' 类型的值转换为预期的参数类型 '[UnlockingCharacters]'”
摆脱var user: UserModel?
在Character
然后就可以找到activeUnlockingCharacters
下的字符了
或类似的东西
UserModel/{uid}/UnlockingCharacters
你(们)能做到
var activeUnlockingCharacters: UnlockingCharacters
数组
var activeUnlockingCharacters: [UnlockingCharacters]
然后使用验证或规则将计数限制为 2
Firebase 有一整节介绍如何处理自定义对象。
https://firebase.google.com/docs/firestore/manage-data/add-data#custom_objects
如果你的所有结构都符合 Codable
do {
try db.collection("UserModel").document("\(uid)").setData(from: userModelObject)
} catch let error {
print("Error writing object to Firestore: \(error)")
}
并阅读
https://firebase.google.com/docs/firestore/query-data/get-data
let docRef = db.collection("UserModel").document("\(uid)")
docRef.getDocument(as: UserModel.self) { result in
// The Result type encapsulates deserialization errors or
// successful deserialization, and can be handled as follows:
//
// Result
// /\
// Error UserModel
switch result {
case .success(let userModel):
// A `Model` value was successfully initialized from the DocumentSnapshot.
print("Model: \(userModel)")
case .failure(let error):
// A `Model` value could not be initialized from the DocumentSnapshot.
print("Error decoding object: \(error)")
}
}
您还可以使用新的@FirestoreQuery
并使用规则来限制可见的对象
在规则中设置用户是唯一可以基于auth读取自己的UserModel的用户。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.