-
Notifications
You must be signed in to change notification settings - Fork 157
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
Firestore customizable encoding for where clauses and update methods #607
base: master
Are you sure you want to change the base?
Conversation
It had become part of commons-internal which kind of defeats the purpose. Also made FirebaseEncoder/FirebaseDecoder an interface in the public API. Useful for writing custom Serializers that have custom behaviour on Firebase
…er' into feature/field-value-encoding
I still need to add Readme/some tests, but feedback would already be appreciated @nbransby as I wont be able to continue until next week |
This reverts commit 4176fe6.
Will anyone ever review this @nbransby 😅 |
Sorry been a crazy month, will hopefully get to it soon |
Does that make this a breaking change? |
looks great to me, I would like to see more comprehensive documentation in the README that would also help me understand the intended usage. |
Yeah, its breaking. I went from:
to
The reason I had to do something is because the new update method has the signature:
and since the original method takes a vararg, it can be called as
I think 1 is a definitive no-go. If you prefer we do 2, Im fine with that as well. Its always gonna be a tradeoff so its pick your poison basically. As for documentation, Ill change that as soon as we agree on this point :) |
I spent long enough trying to think of additional alternatives without joy so, I favour 2 and calling it |
Done @nbransby |
Can you add a little more documentation to the readme? |
Sorry for the slow response, hope its clearer now @nbransby |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good to me, will let @nbransby have the final say
README.md
Outdated
"otherField".to(IntAsStringSerializer(), 1) | ||
|
||
// Overwrite build settings. All fields added after this will have these build settings applied | ||
buildSettings = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Daeda88 can you suggest a better name for this? I find buildSettings confusing in this context
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. I've refactored it to a method called 'encodeNextWith'.
Usage:
documentRef.updateFields {
"field" to "value"
// Set the value of otherField to "1" using a custom Serializer
"otherField".to(IntAsStringSerializer(), 1)
// Overwrite build settings. All fields added after this will have these build settings applied
encodeNextWith {
encodeDefaults = true
serializersModule = module
}
"city" to abstractCity
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not just add encodeWith as an optional arg to the to
function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because then you'd have to add the same block to every call to 'to':
"field".to("value") { encodeDefaults = true }
"otherField".to("otherValue") { encodeDefaults = true }
Just looks less clean in my opinion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes thats not great either. But the blockThatAffectsEverythingBelowIt {}
pattern doesn't feel that intuitive to me.
What about updateFields
taking the encode settings as optional arguments in addition to being able to pass them into the to function, so it would become:
documentRef.updateFields(encodeDefaults = true) {
"field" to "value"
"otherField".to(IntAsStringSerializer(), 1)
"city".to(abstractCity) { serializersModule = module }
}
Although that does beg the question why not just have the encode settings as optional arguments in the to
function also, making it simply:
documentRef.updateFields(encodeDefaults = true) {
"field" to "value"
"otherField".to(IntAsStringSerializer(), 1)
"city".to(abstractCity, serializersModule = module)
}
thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that now, you can set the encodeSettings anywhere in the block:
serializersModule = module
"city" to abstractCity
should be the same as
"city" to abstractCity
serializersModule = module
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so withEncodeSettings
is just to restrict the settings to certain properties otherwise you can just set the encodeSettings at the root level? e.g:
documentRef.updateFields {
"field" to "value"
"otherField".to(IntAsStringSerializer(), 1)
encodeDefaults = true
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct. You can set the encodeSettings directly in the root dsl as well. The withEncodeSettings
block allows for setting custom settings that apply only to the values added within the block. Seems like the nicest way to me. Its flexible and relatively readable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah it's much better - I even think it's not necessary to also accept the settings as optional arguments to updateFields
, so:
documentRef.updateFields(encodeDefaults = true) {
"field" to "value"
"otherField".to(IntAsStringSerializer(), 1)
withEncodeSettings {
serializersModule = module
"city" to abstractCity
}
}
becomes:
documentRef.updateFields {
encodeDefaults = true
"field" to "value"
"otherField".to(IntAsStringSerializer(), 1)
withEncodeSettings {
serializersModule = module
"city" to abstractCity
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was already like that :)
Edit: I see I wrote the wrong pseudo code earlier, but it works like your last example now
Fixes #604 and trumps #605
This solution extends all update methods in Firestore to support more advanced update methods. String fields and FieldPaths can now be used interchangably and custom serializer can be passed.
becomes
Note that the existing vararg pairs can still be used.
Similar support has been added to
where
clauses as well asstartAt
/endAt
/etc:There is a small regression on the existing update methods in that
public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair<String, Any?>, buildSettings: EncodeSettings.Builder.() -> Unit)
changed topublic fun update(documentRef: DocumentReference, buildSettings: EncodeSettings.Builder.() -> Unit, vararg fieldsAndValues: Pair<String, Any?>)
due to Kotlin not being able to figure out which update method to use.Furthermore, I've split the Firestore tests into a few different files and extended them so they clean up all data after completion.
Lastly, I discovered bug #613 and fixed it