Как получить временную метку сервера из API Firebase iOS?
У меня есть приложение iOS, которое использует Firebase и в настоящее время содержит несколько словарей с ключами, которые являются объектами NSDate. Очевидная проблема заключается в том, что NSDate извлекает из системного времени устройства, что не является универсальным.
С чем, лучший способ получить временную метку сервера (похожую на Firebase.ServerValue.TIMESTAMP для веб-API) с использованием Firebase iOS API, чтобы хронологически сортировать ключи словаря?
Я также знаю хронологическую природу идентификаторов, сгенерированных childByAutoID, но я не могу понять, как правильно их сортировать в коде. Хотя они могут быть возвращены в хронологическом порядке, в любой момент на них называется что-то вроде allKeys, порядок выходит из окна.
Любая помощь с этой проблемой будет принята с благодарностью!
Ответы
Ответ 1
Обновление: В Firebase 3.0 + Swift вы можете использовать
FIRServerValue.timestamp()
. В Objective-C это [FIRServerValue timestamp]
.
В Swift теперь вы можете использовать FirebaseServerValue.timestamp()
с Firebase 2.0.3+ (до 3.0).
Эквивалент для Firebase.ServerValue.TIMESTAMP
в iOS равен kFirebaseServerValueTimestamp
. Сейчас это работает только для Objective-C, а не для Swift.
В Swift вы можете создать собственную глобальную метку времени с помощью
let kFirebaseServerValueTimestamp = [".sv":"timestamp"]
и тогда вы сможете использовать kFirebaseServerValueTimestamp
тем же способом.
Но вы можете использовать это только как значение или приоритет node. Вы не сможете установить его как имя ключа (хотя, я тоже не думаю, что вы могли бы в Web API).
В общем случае вызов allKeys
в словаре не гарантирует порядок. Но если вы используете childByAutoID
в node, вы можете получить верните правильный порядок, заказывая NSArray, возвращенный allKeys
лексикографически. Что-то вроде этого будет работать:
[ref observeEventType:FEventTypeValue withBlock:^(FDataSnapshot *snapshot) {
NSDictionary *value = snapshot.value;
NSLog(@"Unsorted allKeys: %@", value.allKeys);
NSArray *sortedAllKeys = [value.allKeys sortedArrayUsingSelector:@selector(compare:)];
NSLog(@"Sorted allKeys: %@", sortedArray);
}];
Это похоже на сортировку NSArray в алфавитном порядке, но при сортировке автоматически сгенерированных идентификаторов вам не нужна локализованная или нечувствительная к регистру сортировка, поэтому вы используете compare:
вместо localizedCaseInsensitiveCompare:
Ответ 2
Предостережение: Кажется, что добавлена метка времени ПОСЛЕ, ваш объект сохраняется в Firebase. Это означает, что если у вас есть тег событий .Value, настроенный на том месте, где сохраняется ваш объект, он будет запущен TWICE. Один раз для первоначального объекта, хранящегося в местоположении, и снова для добавления метки времени. Борясь с этой проблемой в течение нескольких дней: (
Полезная информация для всех, кто не может понять, почему их слушатели событий запускаются дважды/несколько раз!
Ответ 3
В Firebase 4.0 вы можете использовать ServerValue.timestamp()
например:
let ref = Database.database().reference().child("userExample")
let values = ["fullName": "Joe Bloggs", "timestamp": ServerValue.timestamp()] as [String : Any]
ref.updateChildValues(values) { (err, ref) in
if let err = err {
print("failed to upload user data", err)
return
}
}
Ответ 4
Вы можете получить временную печать с помощью FIRServerValue.timestamp().
Но из-за прослушивателя FIRServerValue.timestamp() вызывается два раза. Слушатель будет вызываться два раза.