Skip to content

Firestore: support updating an individual field with pojo as a value #6711

Description

@menulis

Current Firestore (1.30.0+) does not support updating an individual field with pojo as a value, thus the following code

data class Test(
    val primitiveField: String,
    val complexField: Test2
)

data class Test2(
    val primitiveField1: String,
    val primitiveField2: Int
)

val firestore = FirestoreOptions.getDefaultInstance().service

fun main() {
    val test = Test("test", Test2("test", 123))
    val docRef = firestore.collection("test").document("test")
    docRef.set(test).get()
    docRef.update("complexField", Test2("updated test", 456)).get()
}

yields to the following exception:

Exception in thread "main" com.google.cloud.firestore.FirestoreException: Cannot convert Test2(primitiveField1=updated test, primitiveField2=456) to Firestore Value
	at com.google.cloud.firestore.FirestoreException.invalidState(FirestoreException.java:51)
	at com.google.cloud.firestore.UserDataConverter.encodeValue(UserDataConverter.java:180)
	at com.google.cloud.firestore.DocumentSnapshot.fromObject(DocumentSnapshot.java:89)
	at com.google.cloud.firestore.UpdateBuilder.performUpdate(UpdateBuilder.java:513)
	at com.google.cloud.firestore.UpdateBuilder.performUpdate(UpdateBuilder.java:502)
	at com.google.cloud.firestore.UpdateBuilder.update(UpdateBuilder.java:389)
	at com.google.cloud.firestore.DocumentReference.update(DocumentReference.java:261)

This is because UserDataConverter.encodeValue only accepts either primitive types or list or maps of primitive types (which get encoded recursively). However, I do not see any reason why pojos could not be accepted as valid field values. Further, CustomClassMapper.convertToPlainJavaTypes function used to convert pojos to maps could potentially be (re)used. In other words, the following workaround works (as long as you access the CustomClassMapper class through reflection as it is package-private) as expected:

docRef.update(
    "complexField",
    CustomClassMapper.convertToPlainJavaTypes(Test2("updated test", 456))
).get()

Related issues:

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

api: firestoreIssues related to the Firestore API.type: feature request‘Nice-to-have’ improvement, new feature or different behavior or design.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions