Skip to content

Commit 6225d67

Browse files
Support ServerTimestamps
1 parent a593442 commit 6225d67

File tree

4 files changed

+54
-2
lines changed

4 files changed

+54
-2
lines changed

Firestore/core/src/model/server_timestamp_util.cc

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,38 @@ const char kLocalWriteTimeKey[] = "__local_write_time__";
2828
const char kPreviousValueKey[] = "__previous_value__";
2929
const char kServerTimestampSentinel[] = "server_timestamp";
3030

31+
google_firestore_v1_Value EncodeServerTimestamp(
32+
google_protobuf_Timestamp local_write_time,
33+
absl::optional<google_firestore_v1_Value> previous_value) {
34+
google_firestore_v1_Value result{};
35+
result.which_value_type = google_firestore_v1_Value_map_value_tag;
36+
37+
pb_size_t count = previous_value ? 3 : 2;
38+
39+
auto& map_value = result.map_value;
40+
map_value.fields_count = count;
41+
map_value.fields =
42+
nanopb::MakeArray<google_firestore_v1_MapValue_FieldsEntry>(count);
43+
44+
auto field = map_value.fields;
45+
field->key = nanopb::MakeBytesArray(kTypeKey);
46+
field->value.which_value_type = google_firestore_v1_Value_string_value_tag;
47+
field->value.string_value = nanopb::MakeBytesArray(kServerTimestampSentinel);
48+
49+
++field;
50+
field->key = nanopb::MakeBytesArray(kLocalWriteTimeKey);
51+
field->value.which_value_type = google_firestore_v1_Value_timestamp_value_tag;
52+
field->value.timestamp_value = local_write_time;
53+
54+
if (previous_value) {
55+
++field;
56+
field->key = nanopb::MakeBytesArray(kPreviousValueKey);
57+
field->value = *previous_value;
58+
}
59+
60+
return result;
61+
}
62+
3163
bool IsServerTimestamp(const google_firestore_v1_Value& value) {
3264
if (value.which_value_type != google_firestore_v1_Value_map_value_tag) {
3365
return false;

Firestore/core/src/model/server_timestamp_util.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ namespace model {
2727
// Utility methods to handle ServerTimestamps, which are stored using special
2828
// sentinel fields in MapValues.
2929

30+
/**
31+
* Encodes the backing data for a server timestamp in a Value proto.
32+
*/
33+
google_firestore_v1_Value EncodeServerTimestamp(
34+
google_protobuf_Timestamp local_write_time,
35+
absl::optional<google_firestore_v1_Value> previous_value);
3036
/**
3137
* Returns whether the provided value is a field map that contains the
3238
* sentinel values of a ServerTimestamp.

Firestore/core/src/remote/serializer.cc

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "Firestore/core/src/model/no_document.h"
4343
#include "Firestore/core/src/model/patch_mutation.h"
4444
#include "Firestore/core/src/model/resource_path.h"
45+
#include "Firestore/core/src/model/server_timestamp_util.h"
4546
#include "Firestore/core/src/model/set_mutation.h"
4647
#include "Firestore/core/src/model/verify_mutation.h"
4748
#include "Firestore/core/src/nanopb/byte_string.h"
@@ -78,6 +79,7 @@ using model::DeleteMutation;
7879
using model::Document;
7980
using model::DocumentKey;
8081
using model::DocumentState;
82+
using model::EncodeServerTimestamp;
8183
using model::FieldMask;
8284
using model::FieldPath;
8385
using model::FieldTransform;
@@ -218,8 +220,7 @@ google_firestore_v1_Value Serializer::EncodeFieldValue(
218220
}
219221

220222
case FieldValue::Type::ServerTimestamp:
221-
HARD_FAIL("Unhandled type %s on %s", field_value.type(),
222-
field_value.ToString());
223+
return EncodeServerTimestampValue(field_value.server_timestamp_value());
223224
}
224225
UNREACHABLE();
225226
}
@@ -260,6 +261,17 @@ google_firestore_v1_Value Serializer::EncodeTimestampValue(
260261
return result;
261262
}
262263

264+
google_firestore_v1_Value Serializer::EncodeServerTimestampValue(
265+
const FieldValue::ServerTimestamp& value) const {
266+
auto previous_value =
267+
value.previous_value()
268+
? absl::optional<google_firestore_v1_Value>{EncodeFieldValue(
269+
*value.previous_value())}
270+
: absl::nullopt;
271+
return EncodeServerTimestamp(EncodeTimestamp(value.local_write_time()),
272+
previous_value);
273+
}
274+
263275
google_firestore_v1_Value Serializer::EncodeStringValue(
264276
const std::string& value) const {
265277
google_firestore_v1_Value result{};

Firestore/core/src/remote/serializer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,8 @@ class Serializer {
264264
google_firestore_v1_Value EncodeInteger(int64_t value) const;
265265
google_firestore_v1_Value EncodeDouble(double value) const;
266266
google_firestore_v1_Value EncodeTimestampValue(Timestamp value) const;
267+
google_firestore_v1_Value EncodeServerTimestampValue(
268+
const model::FieldValue::ServerTimestamp& value) const;
267269
google_firestore_v1_Value EncodeStringValue(const std::string& value) const;
268270
google_firestore_v1_Value EncodeBlob(const nanopb::ByteString& value) const;
269271
google_firestore_v1_Value EncodeReference(

0 commit comments

Comments
 (0)