Skip to content

Commit 5db2238

Browse files
Backport ServerTimestamp type order changes (#1379)
1 parent 3f5146f commit 5db2238

File tree

2 files changed

+45
-58
lines changed

2 files changed

+45
-58
lines changed

firebase-firestore/src/main/java/com/google/firebase/firestore/UserDataWriter.java

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,18 @@
1616

1717
import static com.google.firebase.firestore.model.ServerTimestamps.getLocalWriteTime;
1818
import static com.google.firebase.firestore.model.ServerTimestamps.getPreviousValue;
19-
import static com.google.firebase.firestore.model.ServerTimestamps.isServerTimestamp;
19+
import static com.google.firebase.firestore.model.Values.TYPE_ORDER_ARRAY;
20+
import static com.google.firebase.firestore.model.Values.TYPE_ORDER_BLOB;
21+
import static com.google.firebase.firestore.model.Values.TYPE_ORDER_BOOLEAN;
22+
import static com.google.firebase.firestore.model.Values.TYPE_ORDER_GEOPOINT;
23+
import static com.google.firebase.firestore.model.Values.TYPE_ORDER_MAP;
24+
import static com.google.firebase.firestore.model.Values.TYPE_ORDER_NULL;
25+
import static com.google.firebase.firestore.model.Values.TYPE_ORDER_NUMBER;
26+
import static com.google.firebase.firestore.model.Values.TYPE_ORDER_REFERENCE;
27+
import static com.google.firebase.firestore.model.Values.TYPE_ORDER_SERVER_TIMESTAMP;
28+
import static com.google.firebase.firestore.model.Values.TYPE_ORDER_STRING;
29+
import static com.google.firebase.firestore.model.Values.TYPE_ORDER_TIMESTAMP;
30+
import static com.google.firebase.firestore.model.Values.typeOrder;
2031
import static com.google.firebase.firestore.util.Assert.fail;
2132

2233
import androidx.annotation.RestrictTo;
@@ -52,31 +63,30 @@ public class UserDataWriter {
5263
}
5364

5465
Object convertValue(Value value) {
55-
switch (value.getValueTypeCase()) {
56-
case MAP_VALUE:
57-
if (isServerTimestamp(value)) {
58-
return convertServerTimestamp(value);
59-
}
66+
switch (typeOrder(value)) {
67+
case TYPE_ORDER_MAP:
6068
return convertObject(value.getMapValue().getFieldsMap());
61-
case ARRAY_VALUE:
69+
case TYPE_ORDER_ARRAY:
6270
return convertArray(value.getArrayValue());
63-
case REFERENCE_VALUE:
71+
case TYPE_ORDER_REFERENCE:
6472
return convertReference(value);
65-
case TIMESTAMP_VALUE:
73+
case TYPE_ORDER_TIMESTAMP:
6674
return convertTimestamp(value.getTimestampValue());
67-
case NULL_VALUE:
75+
case TYPE_ORDER_SERVER_TIMESTAMP:
76+
return convertServerTimestamp(value);
77+
case TYPE_ORDER_NULL:
6878
return null;
69-
case BOOLEAN_VALUE:
79+
case TYPE_ORDER_BOOLEAN:
7080
return value.getBooleanValue();
71-
case INTEGER_VALUE:
72-
return value.getIntegerValue();
73-
case DOUBLE_VALUE:
74-
return value.getDoubleValue();
75-
case STRING_VALUE:
81+
case TYPE_ORDER_NUMBER:
82+
return value.getValueTypeCase().equals(Value.ValueTypeCase.INTEGER_VALUE)
83+
? (Object) value.getIntegerValue() // Cast to Object to prevent type coercion to double
84+
: (Object) value.getDoubleValue();
85+
case TYPE_ORDER_STRING:
7686
return value.getStringValue();
77-
case BYTES_VALUE:
87+
case TYPE_ORDER_BLOB:
7888
return Blob.fromByteString(value.getBytesValue());
79-
case GEO_POINT_VALUE:
89+
case TYPE_ORDER_GEOPOINT:
8090
return new GeoPoint(
8191
value.getGeoPointValue().getLatitude(), value.getGeoPointValue().getLongitude());
8292
default:

firebase-firestore/src/main/java/com/google/firebase/firestore/model/Values.java

Lines changed: 17 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,22 @@ public class Values {
4040
public static final Value NULL_VALUE =
4141
Value.newBuilder().setNullValue(NullValue.NULL_VALUE).build();
4242

43-
/** The order of types in Firestore; this order is defined by the backend. */
43+
/**
44+
* The order of types in Firestore. This order is based on the backend's ordering, but modified to
45+
* support server timestamps.
46+
*/
4447
public static final int TYPE_ORDER_NULL = 0;
4548

4649
public static final int TYPE_ORDER_BOOLEAN = 1;
4750
public static final int TYPE_ORDER_NUMBER = 2;
4851
public static final int TYPE_ORDER_TIMESTAMP = 3;
49-
public static final int TYPE_ORDER_STRING = 4;
50-
public static final int TYPE_ORDER_BLOB = 5;
51-
public static final int TYPE_ORDER_REFERENCE = 6;
52-
public static final int TYPE_ORDER_GEOPOINT = 7;
53-
public static final int TYPE_ORDER_ARRAY = 8;
54-
public static final int TYPE_ORDER_MAP = 9;
52+
public static final int TYPE_ORDER_SERVER_TIMESTAMP = 4;
53+
public static final int TYPE_ORDER_STRING = 5;
54+
public static final int TYPE_ORDER_BLOB = 6;
55+
public static final int TYPE_ORDER_REFERENCE = 7;
56+
public static final int TYPE_ORDER_GEOPOINT = 8;
57+
public static final int TYPE_ORDER_ARRAY = 9;
58+
public static final int TYPE_ORDER_MAP = 10;
5559

5660
/** Returns the backend's type order of the given Value type. */
5761
public static int typeOrder(Value value) {
@@ -78,7 +82,7 @@ public static int typeOrder(Value value) {
7882
return TYPE_ORDER_ARRAY;
7983
case MAP_VALUE:
8084
if (isServerTimestamp(value)) {
81-
return TYPE_ORDER_TIMESTAMP;
85+
return TYPE_ORDER_SERVER_TIMESTAMP;
8286
}
8387
return TYPE_ORDER_MAP;
8488
default:
@@ -106,23 +110,13 @@ public static boolean equals(Value left, Value right) {
106110
return arrayEquals(left, right);
107111
case TYPE_ORDER_MAP:
108112
return objectEquals(left, right);
109-
case TYPE_ORDER_TIMESTAMP:
110-
return timestampEquals(left, right);
113+
case TYPE_ORDER_SERVER_TIMESTAMP:
114+
return getLocalWriteTime(left).equals(getLocalWriteTime(right));
111115
default:
112116
return left.equals(right);
113117
}
114118
}
115119

116-
private static boolean timestampEquals(Value left, Value right) {
117-
if (isServerTimestamp(left) && isServerTimestamp(right)) {
118-
return getLocalWriteTime(left).equals(getLocalWriteTime(right));
119-
} else if (isServerTimestamp(left) || isServerTimestamp(right)) {
120-
return false;
121-
}
122-
123-
return left.getTimestampValue().equals(right.getTimestampValue());
124-
}
125-
126120
private static boolean numberEquals(Value left, Value right) {
127121
if (left.getValueTypeCase() == Value.ValueTypeCase.INTEGER_VALUE
128122
&& right.getValueTypeCase() == Value.ValueTypeCase.INTEGER_VALUE) {
@@ -197,7 +191,9 @@ public static int compare(Value left, Value right) {
197191
case TYPE_ORDER_NUMBER:
198192
return compareNumbers(left, right);
199193
case TYPE_ORDER_TIMESTAMP:
200-
return compareTimestamps(left, right);
194+
return compareTimestamps(left.getTimestampValue(), right.getTimestampValue());
195+
case TYPE_ORDER_SERVER_TIMESTAMP:
196+
return compareTimestamps(getLocalWriteTime(left), getLocalWriteTime(right));
201197
case TYPE_ORDER_STRING:
202198
return left.getStringValue().compareTo(right.getStringValue());
203199
case TYPE_ORDER_BLOB:
@@ -235,30 +231,11 @@ private static int compareNumbers(Value left, Value right) {
235231
throw fail("Unexpected values: %s vs %s", left, right);
236232
}
237233

238-
private static int compareTimestamps(Value left, Value right) {
239-
if (isServerTimestamp(left)) {
240-
if (isServerTimestamp(right)) {
241-
return compareTimestamps(getLocalWriteTime(left), getLocalWriteTime(right));
242-
} else {
243-
// Server timestamps come after all concrete timestamps.
244-
return 1;
245-
}
246-
} else {
247-
if (isServerTimestamp(right)) {
248-
// Server timestamps come after all concrete timestamps.
249-
return -1;
250-
} else {
251-
return compareTimestamps(left.getTimestampValue(), right.getTimestampValue());
252-
}
253-
}
254-
}
255-
256234
private static int compareTimestamps(Timestamp left, Timestamp right) {
257235
int cmp = Util.compareLongs(left.getSeconds(), right.getSeconds());
258236
if (cmp != 0) {
259237
return cmp;
260238
}
261-
262239
return Util.compareIntegers(left.getNanos(), right.getNanos());
263240
}
264241

0 commit comments

Comments
 (0)