【发布时间】:2021-03-19 00:52:13
【问题描述】:
我从 firestore 文档中的以下代码开始,只更改了变量名称等...
private func customClassGetDocument() {
// [START custom_type]
let docRef = db.collection("cities").document("BJ")
docRef.getDocument { (document, error) in
// Construct a Result type to encapsulate deserialization errors or
// successful deserialization. Note that if there is no error thrown
// the value may still be `nil`, indicating a successful deserialization
// of a value that does not exist.
//
// There are thus three cases to handle, which Swift lets us describe
// nicely with built-in Result types:
//
// Result
// /\
// Error Optional<City>
// /\
// Nil City
let result = Result {
try document?.data(as: City.self)
}
switch result {
case .success(let city):
if let city = city {
// A `City` value was successfully initialized from the DocumentSnapshot.
print("City: \(city)")
} else {
// A nil value was successfully initialized from the DocumentSnapshot,
// or the DocumentSnapshot was nil.
print("Document does not exist")
}
case .failure(let error):
// A `City` value could not be initialized from the DocumentSnapshot.
print("Error decoding city: \(error)")
}
}
这是我的代码。首先,一个简单的自定义对象。 myFriends 数组是我从 firestore 读取的单个文档中加载的。
struct Friends: Identifiable, Hashable, Codable {
@DocumentID var id: String?
var myFriends: [String] = []
}
这是我的类,我在其中定义了一个存储库来管理我的朋友对象。 (获取、添加、更新等)
class FriendRepository: ObservableObject {
private let store = Firestore.firestore()
private let friendPath: String = "MyFriends"
@Published var friendIDs: [String] = []
var userId = ""
private let authenticationService = AuthenticationService()
private var cancellables: Set<AnyCancellable> = []
init() {
authenticationService.$user
.compactMap { user in
user?.uid
}
.assign(to: \.userId, on: self)
.store(in: &cancellables)
authenticationService.$user
.receive(on: DispatchQueue.main)
.sink { [weak self] _ in
self?.get()
}
.store(in: &cancellables)
}
func get( ) {
store.collection(friendPath).document(userId).getDocument {(document, error) in
let result = Result {
try document?.data(as: Friends.self)
}
switch result {
case .success(let f):
if let f = f {
print("friends: \(f.myFriends)")
self.friendIDs = f.myFriends
} else {
print("Document does not exist")
}
case .failure(let error):
print("Error decoding city: \(error)")
}
}
}
最后,在主内容视图中,我实例化一个这样的实例 -
@ObservedObject var friendRepository = FriendRepository()
那时我在控制台中看到以下输出
friends: ["PHyUe6mAc3LodM5guJJU"]
friends: ["PHyUe6mAc3LodM5guJJU"]
不知何故,我最终通过简单地实例化我的类的一个实例来调用 get() 函数两次,但我无法弄清楚这段代码是如何/为什么这样做的。
【问题讨论】:
-
什么是
AuthenticationService?它的user属性是什么?您正在订阅它的更改,因此如果它两次发出该值,则您调用self.get()两次 -
我认为你在这里有所收获,新开发者。我抓住了那段代码,以便从可编码开始,但似乎对我有一些副作用。仔细研究一下 - 谢谢。
-
你修好了吗?如果是这样,您可以将其发布为答案吗?如果没有,您能否提供
AuthenticationService实施以进行故障排除?谢谢
标签: swift struct google-cloud-firestore swiftui