Skip to content

Implement POJO field reads. #83

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions firebase-firestore/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
- [feature] Custom objects (POJOs) can now be passed as a field value in
update(), within `Map<>` objects passed to set(), in array transform
operations, and in query filters.
- [feature] DocumentSnapshot.get() now supports retrieving fields as
custom objects (POJOs) by passing a Class<T> instance, e.g.
`snapshot.get("field", CustomType.class)`.

# 17.1.2
- [changed] Changed the internal handling for locally updated documents that
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,28 @@ public void testAPIsAcceptPOJOsForFields() {
waitFor(Tasks.whenAll(tasks));
}

@Test
public void testDocumentSnapshotGetWithPOJOs() {
DocumentReference ref = testDocument();

// Go offline so that we can verify server timestamp behavior overload.
ref.getFirestore().disableNetwork();

POJO pojo = new POJO(1.0, "a", ref);
ref.set(map("field", pojo));

DocumentSnapshot snap = waitFor(ref.get());

assertEquals(pojo, snap.get("field", POJO.class));
assertEquals(pojo, snap.get(FieldPath.of("field"), POJO.class));
assertEquals(
pojo, snap.get("field", POJO.class, DocumentSnapshot.ServerTimestampBehavior.DEFAULT));
assertEquals(
pojo,
snap.get(
FieldPath.of("field"), POJO.class, DocumentSnapshot.ServerTimestampBehavior.DEFAULT));
}

@Test
public void setFieldMaskMustHaveCorrespondingValue() {
CollectionReference collection = testCollection();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,28 @@ public void testServerTimestampsUsesPreviousValueFromLocalMutation() {
assertThat(remoteSnapshot.get("a")).isInstanceOf(Timestamp.class);
}

@Test
public void testServerTimestampBehaviorOverloadsOfDocumentSnapshotGet() {
writeInitialData();
waitFor(docRef.update(updateData));
DocumentSnapshot snap = accumulator.awaitLocalEvent();

// Default behavior should return null timestamp (via any overload).
assertNull(snap.get("when"));
assertNull(snap.get(FieldPath.of("when")));
assertNull(snap.get("when", Timestamp.class));
assertNull(snap.get(FieldPath.of("when"), Timestamp.class));

// Estimate should return a Timestamp object (via any overload).
assertThat(snap.get("when", ServerTimestampBehavior.ESTIMATE)).isInstanceOf(Timestamp.class);
assertThat(snap.get(FieldPath.of("when"), ServerTimestampBehavior.ESTIMATE))
.isInstanceOf(Timestamp.class);
assertThat(snap.get("when", Timestamp.class, ServerTimestampBehavior.ESTIMATE))
.isInstanceOf(Timestamp.class);
assertThat(snap.get(FieldPath.of("when"), Timestamp.class, ServerTimestampBehavior.ESTIMATE))
.isInstanceOf(Timestamp.class);
}

@Test
public void testServerTimestampsWorkViaTransactionSet() {
waitFor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,69 @@ public Object get(
firestore.getFirestoreSettings().areTimestampsInSnapshotsEnabled()));
}

/**
* Returns the value at the field, converted to a POJO, or null if the field or document doesn't
* exist.
*
* @param field The path to the field
* @param valueType The Java class to convert the field value to.
* @return The value at the given field or null.
*/
@Nullable
public <T> T get(@NonNull String field, @NonNull Class<T> valueType) {
return get(FieldPath.fromDotSeparatedPath(field), valueType, ServerTimestampBehavior.DEFAULT);
}

/**
* Returns the value at the field, converted to a POJO, or null if the field or document doesn't
* exist.
*
* @param field The path to the field
* @param valueType The Java class to convert the field value to.
* @param serverTimestampBehavior Configures the behavior for server timestamps that have not yet
* been set to their final value.
* @return The value at the given field or null.
*/
@Nullable
public <T> T get(
@NonNull String field,
@NonNull Class<T> valueType,
@NonNull ServerTimestampBehavior serverTimestampBehavior) {
return get(FieldPath.fromDotSeparatedPath(field), valueType, serverTimestampBehavior);
}

/**
* Returns the value at the field, converted to a POJO, or null if the field or document doesn't
* exist.
*
* @param fieldPath The path to the field
* @param valueType The Java class to convert the field value to.
* @return The value at the given field or null.
*/
@Nullable
public <T> T get(@NonNull FieldPath fieldPath, @NonNull Class<T> valueType) {
return get(fieldPath, valueType, ServerTimestampBehavior.DEFAULT);
}

/**
* Returns the value at the field, converted to a POJO, or null if the field or document doesn't
* exist.
*
* @param fieldPath The path to the field
* @param valueType The Java class to convert the field value to.
* @param serverTimestampBehavior Configures the behavior for server timestamps that have not yet
* been set to their final value.
* @return The value at the given field or null.
*/
@Nullable
public <T> T get(
@NonNull FieldPath fieldPath,
@NonNull Class<T> valueType,
@NonNull ServerTimestampBehavior serverTimestampBehavior) {
Object data = get(fieldPath, serverTimestampBehavior);
return data == null ? null : CustomClassMapper.convertToCustomClass(data, valueType);
}

/**
* Returns the value of the field as a boolean. If the value is not a boolean this will throw a
* runtime exception.
Expand Down