#swift #google-cloud-firestore
# #быстрый #google-cloud-firestore
Вопрос:
Путаница в типах данных Firestore:
Я пытаюсь загрузить пользовательский документ, но исключая тривиальные поля, в качестве поля другого документа Firestore. Что-то вроде «мини-документа пользователя», содержащего только его uid, имя пользователя, имя и фотографию профиля.
Почему в документации Firestore для «Добавления данных» указано, что пользовательские объекты поддерживаются, но в разделе «Поддерживаемые типы данных» объекты не перечислены?
Проблема под рукой:
В нем говорится, что пользовательские объекты преобразуются в поддерживаемые типы данных, однако, когда я следую документации, я получаю сообщение об ошибке при загрузке моего объекта:
Terminating app due to uncaught exception 'FIRInvalidArgumentException', reason: 'Unsupported type: __SwiftValue (found in field tempUserA)'
public class ConsolidationDataService {
static let instance = ConsolidationDataService()
let db = Firestore.firestore()
func createNewBucket(bucket: Bucket, user: UserDictionary, collections: [String], handler: @escaping(_ completed: Bool)-> ()){
let tempUserA = TempUser(
uid: user.uid,
username: user.username,
profileImageURL: user.profileImageURL,
fullname: user.fullname
)
let tempUserB = TempUser(
uid: "",
username: "",
profileImageURL: "",
fullname: ""
)
let bucketRef = db.collection("ConsolidatedBuckets").document()
let consolidatedId = bucketRef.documentID
let consolidatedBucket = [
"consolidatedBucketId": consolidatedId,
"bucketTitle": bucket.bucketTitle,
"creatorUsername": user.username,
"creatorUid": user.uid,
"bucketLogCount": 1,
"completedCount": 0,
"uncompletedCount": 1,
"bucketIds": [bucket.bucketId],
"bucketImages": [],
"collectionIds": [],
"tempUserA": tempUserA,
"tempUserB": tempUserB
] as [String : Any]
bucketRef.setData(consolidatedBucket){ (error) in
if error != nil {
print("There was an error creating a new document in the ConsolidatedCollection")
handler(false)
} else {
print("Uploaded new bucket in the consolidated bucekts colleciton. Named: (bucket.bucketTitle)")
handler(true)
}
}
}
public struct TempUser: Codable {
let uid: String?
let username: String?
let profileImageURL: String?
let fullname: String?
enum CodingKeys: String, CodingKey {
case uid
case username
case profileImageURL
case fullname
}
}
Я также попытался загрузить объект со словарем в определение структуры для TempUser
пользовательской структуры. Это также не позволяет преобразовать объект в принятые типы данных Firestore.
public struct TempUser: Codable {
let uid: String?
let username: String?
let profileImageURL: String?
let fullname: String?
var dictionary: [String: Any] {
let data = (try? JSONEncoder().encode(self)) ?? Data()
return (try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any]) ?? [:]
}
enum CodingKeys: String, CodingKey {
case uid
case username
case profileImageURL
case fullname
}
}
Вызывающий функцию
ConsolidationDataService.instance.createNewBucket(bucket: uploadedBucket, user: self.user!,
collections: self.collectionsBeingAddedToArray) { (completed) in
if completed {
print("Finished.")
self.showAlert()
}
}
где collectionsBeingAddedToArray
имеет тип [String]
и user
имеет тип UserDictionary
, который является пользовательской структурой для пользовательского объекта.
Ответ №1:
Для оценки второго примера недостаточно информации. В первом случае TempUser
экземпляр struct должен быть преобразован в [String: Any]
словарь.
let encodedTempUserA: [String: Any]
let encodedTempUserB: [String: Any]
do {
encodedTempUserA = try Firestore.Encoder().encode(tempUserA)
encodedTempUserB = try Firestore.Encoder().encode(tempUserB)
} catch {
handleEncodingError(error)
return
}
let consolidatedBucket = [
"consolidatedBucketId": consolidatedId,
"bucketTitle": bucket.bucketTitle,
"creatorUsername": user.username,
"creatorUid": user.uid,
"bucketLogCount": 1,
"completedCount": 0,
"uncompletedCount": 1,
"bucketIds": [bucket.bucketId],
"bucketImages": [],
"collectionIds": [],
"tempUserA": encodedTempUserA,
"tempUserB": encodedTempUserB
] as [String : Any]