Отметка времени Firestore преобразуется в карту при обработке через облачную функцию

У меня проблема с классом firebase.firestore.Timestamp.

Я работаю над приложением Angular 6 с firestore. Некоторое время я без проблем использую метки времени, но сейчас я перевожу некоторые из своих клиентских сервисов в облачные функции.

Проблема в следующем:

Когда я выполняю операцию записи непосредственно со стороны клиента, например:

const doc = { startTimestamp: firebase.firestore.Timestamp.fromDate(new Date()) };
firebase.firestore().doc('some_collection/uid).set(doc);

Документ правильно записывается в firestore в виде отметки времени.

Однако, когда я отправляю документ в облачную функцию, а затем выполняю запись из функции, он записывается как карта, а не как временная метка. Точно так же, если я использую объект JS Date () вместо firestore.Timestamp, он правильно записывается на стороне клиента, но записывается как строка из облачной функции.

Это имеет смысл, учитывая, что документы представляют собой просто JSON в request.body, думаю, я просто надеялся, что firestore будет достаточно умен, чтобы неявно обработать преобразование.

На данный момент у меня есть обходной путь, который просто вручную преобразует объекты в firestore.Timestamps снова в облачной функции, но я надеюсь, что есть более эффективное решение, возможно, что-то похороненное в SDK, которое я не смог найти.

Кто-нибудь еще сталкивался и в идеале нашел решение для этого?

При необходимости я могу предоставить больше примеров кода.


person Alec Daling    schedule 18.11.2018    source источник


Ответы (2)


Наблюдаемое вами поведение является ожидаемым. Клиентские библиотеки Firestore имеют особую интерпретацию объектов типа Timestamp, и при записи они преобразуются в поле типа Timestamp в базе данных. Однако, если вы попытаетесь сериализовать объекты Timestamp как JSON, вы просто получите объект с компонентами timestamp в миллисекундах и наносекундах. Если вы хотите отправить эти компоненты временной метки в Cloud Functions или какое-либо другое программное обеспечение, это нормально, но эта другая часть программного обеспечения должна будет воссоздать реальный объект Timestamp из этих частей перед записью в Firestore с помощью Admin SDK или что-то еще. SDK, который вы используете для работы с Firestore.

person Doug Stevenson    schedule 18.11.2018
comment
Спасибо, это все, что мне нужно было услышать. Мой обходной путь, кажется, работает нормально, просто он не очень чистый. - person Alec Daling; 18.11.2018

в вашей модели класса используйте

@ServerTimestamp var timestamp: Date? = null

or

@ServerTimestamp Date timestamp = null

Вы можете не указывать метку времени инициализации в своем коде, например new Date ()

Пример:

@IgnoreExtraProperties
data class ProductItem(
    var userId: String? = "",
    var avgRating: Double = 0.toDouble(),
    @ServerTimestamp var timestamp: Date? = null
)

or

public class ProductItem() {
    String userId;
    Double avgRating;
    @ServerTimestamp Date timestamp;
}
person Joseph Wambura    schedule 18.11.2018
comment
Честно говоря, я не понимаю, что здесь предлагается. Я не уверен, актуально ли это, но я хотел бы, чтобы мои модели на стороне клиента соответствовали типам, возвращаемым из запроса firestore. Таким образом, у меня есть атрибуты даты на стороне клиента, набранные в виде меток времени вместо дат, потому что я ожидаю, что метки времени будут возвращены запросами. Я не знаком с аннотацией @ServerTimestamp, вы можете указать мне какую-либо документацию? Кроме того, возможно, это не актуально, но я пытаюсь включить даты, которые не обязательно соответствуют текущему времени сервера. - person Alec Daling; 18.11.2018