Я пытаюсь добавить в Firestore объект как документ, у которого свойство Date
автоматически закодировано как FIRTimestamp
. У меня также есть слушатель, который отслеживает любые изменения документа в коллекции.
После добавления документа он кодируется с наносекундной меткой времени с точностью 9 di git, и я сразу слышу обновление от слушателя, которое подтверждает как таковой. Однако после того, как мой обработчик завершения для добавления документа запускается (это означает, что данные теперь отправлены и сохранены в Firestore, а не просто локальное изменение), я слышу другое обновление от слушателя, но теперь наносекунды временной метки в возвращенном документ был сокращен до 6 значащих цифр данных (но все еще состоит из 9 цифр) - последние 3 цифры получают значение 0.
Я озадачен, потому что документация для класса Timestamp Firestore утверждает, что наносекунды могут быть от 0 до 999 999 999. Симулятор iDevice, на котором я работаю, может поддерживать точность 9 di git наносекунд и отправляет это в Firestore, но я получаю что-то другое обратно, что вызывает двойное срабатывание слушателя. Если я отправляю другие данные документа, такие как строка, а не метка времени, то слушатель срабатывает только один раз, как ожидалось (он больше не запускается после запуска обработчика завершения).
Что-то мне здесь не хватает ? Это какая-то проблема с Firestore, так что мне приходится вручную кодировать все мои Date
с точностью до 6 цифр, сниженной до наносекунд, чтобы избежать этих удвоенных обновлений слушателя?
Контроллер представления, который добавляет документ и прослушивает изменения (упрощено):
import SwiftUI
import FirebaseFirestore
class GalleryViewController: UIViewController {
@IBSegueAction func GalleryEmbed(_ coder: NSCoder) -> UIViewController? {
print("Adding")
try? Firestore.firestore().collection("galleryPosts").addDocument(from: GalleryPost()) { (e: Error?) in
print("Done Adding")
}
Firestore.firestore().collection("galleryPosts").addSnapshotListener { (query: QuerySnapshot?, e: Error?) in
print(query?.documentChanges[0].document.data())
}
return UIHostingController(coder: coder, rootView: GalleryView())
}
}
Класс объекта, который кодируется (упрощено):
import SwiftUI
import FirebaseFirestoreSwift
class GalleryPost: Codable, ObservableObject {
@Published public var timestamp: Date
public init(_ timestamp: Date) {
self.timestamp = timestamp
}
enum CodingKeys: CodingKey {
case timestamp
}
public func encode(to encoder: Encoder) throws {
var container: KeyedEncodingContainer<GalleryPost.CodingKeys> = encoder.container(keyedBy: CodingKeys.self)
try container.encode(timestamp, forKey: .timestamp)
}
public required init(from decoder: Decoder) throws {
var container: KeyedDecodingContainer<GalleryPost.CodingKeys> = try decoder.container(keyedBy: CodingKeys.self)
timestamp = try container.decode(Date.self, forKey: .timestamp)
}
}
Пример того, что будет напечатано при добавлении единицы document:
Adding
Optional(["timestamp": <FIRTimestamp: seconds=1594306265 nanoseconds=487436816>])
Done Adding
Optional(["timestamp": <FIRTimestamp: seconds=1594306265 nanoseconds=487436000>])
Интересно отметить, что если бы я отредактировал свою метку времени через веб-сайт, напечаталось бы nanoseconds=0
.