Skip to content

Commit 2e162e3

Browse files
Simplify FieldValueOptions (#541)
1 parent 642b119 commit 2e162e3

File tree

7 files changed

+81
-143
lines changed

7 files changed

+81
-143
lines changed

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

Lines changed: 64 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@
2424
import com.google.firebase.firestore.model.DocumentKey;
2525
import com.google.firebase.firestore.model.value.ArrayValue;
2626
import com.google.firebase.firestore.model.value.FieldValue;
27-
import com.google.firebase.firestore.model.value.FieldValueOptions;
2827
import com.google.firebase.firestore.model.value.ObjectValue;
2928
import com.google.firebase.firestore.model.value.ReferenceValue;
29+
import com.google.firebase.firestore.model.value.ServerTimestampValue;
30+
import com.google.firebase.firestore.model.value.TimestampValue;
3031
import com.google.firebase.firestore.util.CustomClassMapper;
3132
import com.google.firebase.firestore.util.Logger;
3233
import java.util.ArrayList;
@@ -80,6 +81,18 @@ public enum ServerTimestampBehavior {
8081
static final ServerTimestampBehavior DEFAULT = ServerTimestampBehavior.NONE;
8182
}
8283

84+
/** Holds settings that define field value deserialization options. */
85+
static class FieldValueOptions {
86+
final ServerTimestampBehavior serverTimestampBehavior;
87+
final boolean timestampsInSnapshotsEnabled;
88+
89+
private FieldValueOptions(
90+
ServerTimestampBehavior serverTimestampBehavior, boolean timestampsInSnapshotsEnabled) {
91+
this.serverTimestampBehavior = serverTimestampBehavior;
92+
this.timestampsInSnapshotsEnabled = timestampsInSnapshotsEnabled;
93+
}
94+
}
95+
8396
private final FirebaseFirestore firestore;
8497

8598
private final DocumentKey key;
@@ -165,7 +178,7 @@ public Map<String, Object> getData(@NonNull ServerTimestampBehavior serverTimest
165178
? null
166179
: convertObject(
167180
doc.getData(),
168-
FieldValueOptions.create(
181+
new FieldValueOptions(
169182
serverTimestampBehavior,
170183
firestore.getFirestoreSettings().areTimestampsInSnapshotsEnabled()));
171184
}
@@ -286,7 +299,7 @@ public Object get(
286299
serverTimestampBehavior, "Provided serverTimestampBehavior value must not be null.");
287300
return getInternal(
288301
fieldPath.getInternalPath(),
289-
FieldValueOptions.create(
302+
new FieldValueOptions(
290303
serverTimestampBehavior,
291304
firestore.getFirestoreSettings().areTimestampsInSnapshotsEnabled()));
292305
}
@@ -449,7 +462,7 @@ public Date getDate(
449462
Object maybeDate =
450463
getInternal(
451464
FieldPath.fromDotSeparatedPath(field).getInternalPath(),
452-
FieldValueOptions.create(
465+
new FieldValueOptions(
453466
serverTimestampBehavior, /*timestampsInSnapshotsEnabled=*/ false));
454467
return castTypedValue(maybeDate, field, Date.class);
455468
}
@@ -492,8 +505,7 @@ public Timestamp getTimestamp(
492505
Object maybeTimestamp =
493506
getInternal(
494507
FieldPath.fromDotSeparatedPath(field).getInternalPath(),
495-
FieldValueOptions.create(
496-
serverTimestampBehavior, /*timestampsInSnapshotsEnabled=*/ true));
508+
new FieldValueOptions(serverTimestampBehavior, /*timestampsInSnapshotsEnabled=*/ true));
497509
return castTypedValue(maybeTimestamp, field, Timestamp.class);
498510
}
499511

@@ -571,29 +583,56 @@ private Object convertValue(FieldValue value, FieldValueOptions options) {
571583
} else if (value instanceof ArrayValue) {
572584
return convertArray((ArrayValue) value, options);
573585
} else if (value instanceof ReferenceValue) {
574-
ReferenceValue referenceValue = (ReferenceValue) value;
575-
DocumentKey key = (DocumentKey) referenceValue.value(options);
576-
DatabaseId refDatabase = ((ReferenceValue) value).getDatabaseId();
577-
DatabaseId database = this.firestore.getDatabaseId();
578-
if (!refDatabase.equals(database)) {
579-
// TODO: Somehow support foreign references.
580-
Logger.warn(
581-
"DocumentSnapshot",
582-
"Document %s contains a document reference within a different database "
583-
+ "(%s/%s) which is not supported. It will be treated as a reference in "
584-
+ "the current database (%s/%s) instead.",
585-
key.getPath(),
586-
refDatabase.getProjectId(),
587-
refDatabase.getDatabaseId(),
588-
database.getProjectId(),
589-
database.getDatabaseId());
590-
}
591-
return new DocumentReference(key, firestore);
586+
return convertReference((ReferenceValue) value);
587+
} else if (value instanceof TimestampValue) {
588+
return convertTimestamp((TimestampValue) value, options);
589+
} else if (value instanceof ServerTimestampValue) {
590+
return convertServerTimestamp((ServerTimestampValue) value, options);
591+
} else {
592+
return value.value();
593+
}
594+
}
595+
596+
private Object convertServerTimestamp(ServerTimestampValue value, FieldValueOptions options) {
597+
switch (options.serverTimestampBehavior) {
598+
case PREVIOUS:
599+
return value.getPreviousValue();
600+
case ESTIMATE:
601+
return value.getLocalWriteTime();
602+
default:
603+
return value.value();
604+
}
605+
}
606+
607+
private Object convertTimestamp(TimestampValue value, FieldValueOptions options) {
608+
Timestamp timestamp = value.value();
609+
if (options.timestampsInSnapshotsEnabled) {
610+
return timestamp;
592611
} else {
593-
return value.value(options);
612+
return timestamp.toDate();
594613
}
595614
}
596615

616+
private Object convertReference(ReferenceValue value) {
617+
DocumentKey key = value.value();
618+
DatabaseId refDatabase = value.getDatabaseId();
619+
DatabaseId database = this.firestore.getDatabaseId();
620+
if (!refDatabase.equals(database)) {
621+
// TODO: Somehow support foreign references.
622+
Logger.warn(
623+
"DocumentSnapshot",
624+
"Document %s contains a document reference within a different database "
625+
+ "(%s/%s) which is not supported. It will be treated as a reference in "
626+
+ "the current database (%s/%s) instead.",
627+
key.getPath(),
628+
refDatabase.getProjectId(),
629+
refDatabase.getDatabaseId(),
630+
database.getProjectId(),
631+
database.getDatabaseId());
632+
}
633+
return new DocumentReference(key, firestore);
634+
}
635+
597636
private Map<String, Object> convertObject(ObjectValue objectValue, FieldValueOptions options) {
598637
Map<String, Object> result = new HashMap<>();
599638
for (Map.Entry<String, FieldValue> entry : objectValue.getInternalValue()) {

firebase-firestore/src/main/java/com/google/firebase/firestore/model/value/ArrayValue.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,16 +70,6 @@ public List<Object> value() {
7070
return res;
7171
}
7272

73-
@Override
74-
public List<Object> value(FieldValueOptions options) {
75-
// Recursively convert the array into the value that users will see in document snapshots.
76-
List<Object> res = new ArrayList<>(internalValue.size());
77-
for (FieldValue v : internalValue) {
78-
res.add(v.value(options));
79-
}
80-
return res;
81-
}
82-
8373
public List<FieldValue> getInternalValue() {
8474
return internalValue;
8575
}

firebase-firestore/src/main/java/com/google/firebase/firestore/model/value/FieldValue.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,6 @@ public abstract class FieldValue implements Comparable<FieldValue> {
6363
@Nullable
6464
public abstract Object value();
6565

66-
/**
67-
* Converts a FieldValue into the value that users will see in document snapshots using the
68-
* provided deserialization options.
69-
*/
70-
@Nullable
71-
public Object value(FieldValueOptions options) {
72-
return value();
73-
}
74-
7566
@Override
7667
public abstract boolean equals(Object o);
7768

firebase-firestore/src/main/java/com/google/firebase/firestore/model/value/FieldValueOptions.java

Lines changed: 0 additions & 66 deletions
This file was deleted.

firebase-firestore/src/main/java/com/google/firebase/firestore/model/value/ObjectValue.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,6 @@ public Map<String, Object> value() {
6767
return res;
6868
}
6969

70-
@Override
71-
public Map<String, Object> value(FieldValueOptions options) {
72-
Map<String, Object> res = new HashMap<>();
73-
for (Map.Entry<String, FieldValue> entry : internalValue) {
74-
res.put(entry.getKey(), entry.getValue().value(options));
75-
}
76-
return res;
77-
}
78-
7970
public ImmutableSortedMap<String, FieldValue> getInternalValue() {
8071
return internalValue;
8172
}

firebase-firestore/src/main/java/com/google/firebase/firestore/model/value/ServerTimestampValue.java

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
package com.google.firebase.firestore.model.value;
1616

1717
import com.google.firebase.Timestamp;
18-
import com.google.firebase.firestore.util.Assert;
18+
import com.google.firebase.firestore.DocumentSnapshot;
1919
import javax.annotation.Nullable;
2020

2121
/**
@@ -47,21 +47,23 @@ public Object value() {
4747
return null;
4848
}
4949

50-
@Override
50+
/**
51+
* Returns the value of the field before this ServerTimestamp was set.
52+
*
53+
* <p>Preserving the previous values allows the user to display the last resoled value until the
54+
* backend responds with the timestamp {@link DocumentSnapshot.ServerTimestampBehavior}.
55+
*/
5156
@Nullable
52-
public Object value(FieldValueOptions options) {
53-
switch (options.getServerTimestampBehavior()) {
54-
case PREVIOUS:
55-
return previousValue != null ? previousValue.value(options) : null;
56-
case ESTIMATE:
57-
return new TimestampValue(localWriteTime).value(options);
58-
case NONE:
59-
return null;
60-
default:
61-
throw Assert.fail(
62-
"Unexpected case for ServerTimestampBehavior: %s",
63-
options.getServerTimestampBehavior().name());
57+
public Object getPreviousValue() {
58+
if (previousValue instanceof ServerTimestampValue) {
59+
return ((ServerTimestampValue) previousValue).getPreviousValue();
6460
}
61+
62+
return previousValue != null ? previousValue.value() : null;
63+
}
64+
65+
public Timestamp getLocalWriteTime() {
66+
return localWriteTime;
6567
}
6668

6769
@Override

firebase-firestore/src/main/java/com/google/firebase/firestore/model/value/TimestampValue.java

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,10 @@ public int typeOrder() {
3232

3333
@Override
3434
@NonNull
35-
public Object value() {
35+
public Timestamp value() {
3636
return internalValue;
3737
}
3838

39-
@Override
40-
public Object value(FieldValueOptions options) {
41-
if (options.areTimestampsInSnapshotsEnabled()) {
42-
return internalValue;
43-
} else {
44-
return internalValue.toDate();
45-
}
46-
}
47-
4839
public Timestamp getInternalValue() {
4940
return internalValue;
5041
}

0 commit comments

Comments
 (0)