ОНОВЛЕННЯ: 12 лютого 2018 року - SDK iOS Firestore v0.10.0
Подібно до деяких інших коментаторів, я також помітив повільнішу реакцію на перший запит отримання (з наступними запитами, які займають ~ 100 мс). Для мене це не так погано, як 30-ті роки, але, можливо, приблизно 2-3 секунди, коли я маю хороший зв’язок, цього достатньо, щоб забезпечити поганий досвід роботи користувача при запуску мого додатка.
Firebase повідомили, що їм відомо про цю проблему "холодного старту" і вони працюють над довгостроковим виправленням - на жаль, немає часу прибуття. Я думаю, що це окреме питання, що коли у мене поганий зв’язок, може знадобитися вік (понад 30 років), перш ніж запити приймуть рішення про читання з кешу.
Поки Firebase вирішує всі ці проблеми, я почав використовувати нове disableNetwork()
та enableNetwork()
методи (доступні у Firestore v0.10.0) для ручного контролю стану Інтернету / офлайн у Firebase. Хоча мені довелося бути дуже обережним, де я використовую його у своєму коді, оскільки існує помилка Firestore, яка може спричинити збій за певних сценаріїв.
ОНОВЛЕННЯ: 15 листопада 2017 р. - SDK iOS Firestore v0.9.2
Здається, проблему з повільною продуктивністю виправлено. Я повторно запустив тести, описані нижче, і час, який потрібен Firestore, щоб повернути 100 документів, зараз здається постійно близько 100 мс.
Не впевнений, чи це було виправлення в останньому SDK v0.9.2, чи це виправлення внутрішньої мережі (або в обох випадках), але я пропоную всім оновити свої підрозділи Firebase. Мій додаток значно помітніший - подібний до того, як це було в БД реального часу.
Я також виявив, що Firestore працює набагато повільніше, ніж БД у реальному часі, особливо під час читання з безлічі документів.
Оновлені тести (з останньою iOS Firestore SDK v0.9.0):
Я створив тестовий проект в iOS Swift, використовуючи як RTDB, так і Firestore, і провів по 100 послідовних операцій читання на кожному. Що стосується RTDB, я протестував метод obserSingleEvent і методи спостереження на кожному з 100 вузлів верхнього рівня. Для Firestore я використовував методи getDocument та addSnapshotListener у кожному із 100 документів у колекції TestCol. Я провів тести, постійно вмикаючи та вимикаючи диск. Будь ласка, зверніться до вкладеного зображення, де показано структуру даних для кожної бази даних.
Я провів тест 10 разів для кожної бази даних на одному пристрої та стабільній мережі Wi-Fi. Існуючих спостерігачів та слухачів знищували перед кожним новим прогоном.
Метод БД у режимі реального часу спостерігатиSingleEvent:
func rtdbObserveSingle() {
let start = UInt64(floor(Date().timeIntervalSince1970 * 1000))
print("Started reading from RTDB at: \(start)")
for i in 1...100 {
Database.database().reference().child(String(i)).observeSingleEvent(of: .value) { snapshot in
let time = UInt64(floor(Date().timeIntervalSince1970 * 1000))
let data = snapshot.value as? [String: String] ?? [:]
print("Data: \(data). Returned at: \(time)")
}
}
}
Метод спостереження БД у реальному часі:
func rtdbObserve() {
let start = UInt64(floor(Date().timeIntervalSince1970 * 1000))
print("Started reading from RTDB at: \(start)")
for i in 1...100 {
Database.database().reference().child(String(i)).observe(.value) { snapshot in
let time = UInt64(floor(Date().timeIntervalSince1970 * 1000))
let data = snapshot.value as? [String: String] ?? [:]
print("Data: \(data). Returned at: \(time)")
}
}
}
Метод getDocument Firestore:
func fsGetDocument() {
let start = UInt64(floor(Date().timeIntervalSince1970 * 1000))
print("Started reading from FS at: \(start)")
for i in 1...100 {
Firestore.firestore().collection("TestCol").document(String(i)).getDocument() { document, error in
let time = UInt64(floor(Date().timeIntervalSince1970 * 1000))
guard let document = document, document.exists && error == nil else {
print("Error: \(error?.localizedDescription ?? "nil"). Returned at: \(time)")
return
}
let data = document.data() as? [String: String] ?? [:]
print("Data: \(data). Returned at: \(time)")
}
}
}
Метод addSnapshotListener Firestore:
func fsAddSnapshotListener() {
let start = UInt64(floor(Date().timeIntervalSince1970 * 1000))
print("Started reading from FS at: \(start)")
for i in 1...100 {
Firestore.firestore().collection("TestCol").document(String(i)).addSnapshotListener() { document, error in
let time = UInt64(floor(Date().timeIntervalSince1970 * 1000))
guard let document = document, document.exists && error == nil else {
print("Error: \(error?.localizedDescription ?? "nil"). Returned at: \(time)")
return
}
let data = document.data() as? [String: String] ?? [:]
print("Data: \(data). Returned at: \(time)")
}
}
}
Кожен метод по суті друкує мітку часу unix у мілісекундах, коли метод починає виконуватися, а потім друкує іншу мітку часу unix, коли повертається кожна операція читання. Я взяв різницю між початковою міткою часу та останньою міткою часу, щоб повернутися.
РЕЗУЛЬТАТИ - Вимкнено стійкість диска:
РЕЗУЛЬТАТИ - Увімкнено стійкість диска:
Структура даних:
Коли способи Firestore getDocument / addSnapshotListener застряють, здається, вони застрягли на тривалість, яка приблизно дорівнює 30 секундам. Можливо, це може допомогти команді Firebase виділити, де в SDK вона застряє?