#ios #swift #firebase #google-cloud-firestore
#iOS #swift #firebase #google-облако-firestore
Вопрос:
Я не могу найти в Интернете, как сохранить массив объектов так, чтобы ключ «line_items» представлял числа для каждого элемента меню со значениями для каждого элемента меню, соответствующими его собственному номеру. Другими словами, мне нужно, чтобы после line_items шли числа, а не вложенный ключ, чтобы можно было быстро ссылаться на каждый отдельный объект MenuItem. Я нашел в Интернете, как сделать так, чтобы каждый ключ имел массив значений, но мне нужно, чтобы line_items имел массив объектов MenuItem. Происходит сбой следующего кода:
public func uploadTransactionData(_ menuItems: [MenuItem], balanceId: String, subTotal: Int, completion: @escaping (() -> ())) {
guard let userId = Auth.auth().currentUser?.uid else { completion(); return }
let utilitiesManager = UtilitiesManager()
let timestamp = utilitiesManager.timestamp()
let params: [String: Any] = ["date": "(timestamp)",
"balance_id": "(balanceId)",
"subtotal": "(subTotal)",
"user_id": "(userId)",
"line_items": menuItems
]
Firestore.firestore().document("transaction_history/(timestamp)").setData(params)
{ err in
if let e = err {
print("$-- error creating user (e)")
completion()
} else {
completion()
}
}
}
Вот модель MenuItem:
struct MenuItem {
let itemId: String
let name: String
var modifiers: [String]?
var photoName: String?
var photoUrl: String?
var quantity: Int
var price: Int
var sizeAddOnPrice: Int
var toppingsAddOnPrice: Int
let description: String
var size: String
let category: String
init(itemId: String, name: String, modifiers: [String]?, photoName: String?, photoUrl: String?, quantity: Int, price: Int, sizeAddOnPrice: Int, toppingsAddOnPrice: Int, description: String, size: String, category: String) {
self.itemId = itemId
self.name = name
self.modifiers = modifiers
self.photoName = photoName
self.photoUrl = photoUrl
self.quantity = quantity
self.price = price
self.sizeAddOnPrice = sizeAddOnPrice
self.toppingsAddOnPrice = toppingsAddOnPrice
self.description = description
self.size = size
self.category = category
}
Комментарии:
1. Не могли бы вы, пожалуйста, добавить, какую ошибку вы получаете?
2. *** Завершение работы приложения из-за неперехваченного исключения ‘FIRInvalidArgumentException’, причина: ‘Неподдерживаемый тип: _SwiftValue’
3. Firestore никогда не узнает, что такое MenuItem. Пожалуйста, взгляните сюда: firebase.google.com/docs/firestore/manage-data/data-types это типы данных, поддерживаемые Firestore.
Ответ №1:
Проблема:
Ваше приложение выходит из строя, потому что вы пытаетесь сохранить пользовательский объект MenuItem
в Firestore. Firestore этого не позволяет. Firestore поддерживает только эти типы данных.
Решение:
Вы можете преобразовать свой пользовательский объект MenuItem
в типы данных, поддерживаемые Firestore. Вы можете сделать это, внеся следующие изменения в свой код.
-
Сделайте
MenuItem
подтверждениеCodable
протоколу.struct MenuItem: Codable { // Your code as it is. }
-
Внесите следующие изменения в свою
uploadTransactionData()
функцию:public func uploadTransactionData(_ menuItems: [MenuItem], balanceId: String, subTotal: Int, completion: @escaping (() -> ())) { let userId = Auth.auth().currentUser?.uid else { completion(); return } let utilitiesManager = UtilitiesManager() let timestamp = utilitiesManager.timestamp() var list_menuItem = [Any]() for item in menuItems { do { let jsonData = try JSONEncoder().encode(item) let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: []) list_menuItem.append(jsonObject) } catch { // handle error } } let params: [String: Any] = ["date": "(timestamp)", "balance_id": "(balanceId)", "subtotal": "(subTotal)", "user_id": "(userId)", "line_items": list_menuItem ] Firestore.firestore().document("transaction_history/(timestamp)").setData(params) { err in if let e = err { print("$-- error creating user (e)") completion() } else { completion() } } }
Ответ №2:
Это потому, что Firestore не знает, как сохранить значение: MenuItems
you can map it like this: "objectExample": [
"a": 5,
"b": [
"nested": "foo"
]
]
или:
.setData([
"name": "Frank",
"favorites": [ "food": "Pizza", "color": "Blue", "subject": "recess" ],
"age": 12
])