-
Notifications
You must be signed in to change notification settings - Fork 4k
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
feat(cloud_firestore): Move Snapshot handling into a EventChannel #4209
Conversation
...d_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart
Outdated
Show resolved
Hide resolved
@Salakar this has spiralled quite a bit. The
I have noticed there are no tests for snapshot cancellations (else, I'd have App crashes ;-)) so those should be added at some point. The PR needs a lot more work, but please let me know if it's acceptable to work on above 4 components in the same PR. I prefer PRs to be smaller normally... |
Do you mean in the example app or in the e2e tests? I thought we had some in e2e; https://github.com/FirebaseExtended/flutterfire/tree/master/packages/cloud_firestore/cloud_firestore/example/test_driver - could be wrong though 😅 any additional tests you can add to e2e tests here would be extremely welcome!
I don't mind either way. If you feel like you can break it down into smaller PRs that can function independently then be my guest - might make it easier on the review, otherwise a single PR is also fine - CI should cover most things before getting to review anyway. |
Hey @ened Thanks for starting this. I do have one question, since a lot of the current implementation was built on-top of the original code, we used Originally, it was sending the result of a Transaction (anything the user returns) back to native, and then native sent that back to Dart land. The problem was, if the user sent a class or something to native you couldn't serialize it over the bridge & it'd throw an error. I noticed you've got a In the rework, I kept everything stored in Dart land (see here), and when the transaction finishes, I then pluck that value out and return it as the transaction result (see here). This way, it keeps away from native and the user can return whatever they like. Sending and storing data on native works for primitive values like numbers and strings, but it'll break when trying to return something else, such as a |
Essentially, 2 snapshot observers (for the same query or document) should be opened simultaneously and the result of
A single PR it is. There is actually quite a bit of overlap on the Dart side which is better to read when in context. Thank you. |
@Ehesp hi
For the non-native types Firestore utilises FirestoreMessageCodec which handles the conversion from Firestore objects like In your examples only I think it is not a problem, let's go through the code.
Therefore, the developer defined, non-firebase, objects never cross Dart <-> Native. Only the Firebase objects do. There is a missing piece with transaction as the transaction here could still fail ( |
@ened Thanks - I'll put some time aside soon to review this however your comments generally make sense. Yeah the I've not properly read through the code yet, only skimmed so I probably missed a few things. |
If you can look at Auth also that would be super helpful - our plate is quite full at the moment with NNBD changes so any help with PRs is appreciated. @Ehesp is also mostly out of office now for a few weeks so replies may be slow. One to keep in mind; on the Auth side of things @mikehardy is working on upgrading native Firebase SDKs on all plugins so once this is done we can switch the auth e2e testing to use the new Firebase Auth Emulator which should reduce flakiness/improve local testing - shouldn't be a blocker for you but may land mid-PR. cc @rrousselGit also for a final review if you can please. My quick glance at native bits and this LGTM (though not fully reviewed). With @russellwheatley & @rrousselGit approval I'm happy to ship |
// This is a example use for "snapshots in sync". | ||
// The view reflects the time of the last Firestore sync; which happens any time a field is updated. | ||
StreamBuilder( | ||
stream: FirebaseFirestore.instance.snapshotsInSync(), |
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.
Not blocker but: It's not a good practice to create a new Stream directly inside the build
method.
Since we're inside a StatefulWidget, this could be moved as property of State
(and ideally same thing for the other streams in build
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.
Maybe snapshotsInSync
should be a getter and cached instead, for convenience. But that's a breaking change
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.
I don't disagree, however I believe those example projects try to convene the point of how to use the API above best coding practices. The way it's written now requires a developer to only look at a single place to see how the streams are used.
Moving it into initState
will then require a dispose()
call too
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.
We wouldn't need a dispose as there is nothing to dispose of.
It'd just be:
class MyState extends State<T> {
final stream = FirebaseFirestore.instance.snapshotsInSync();
}
As an example, I believe it's important to show good practices, as other people will rely on those in their application. If the example uses a bad practice, that may make the bad practice propagate
packages/cloud_firestore/cloud_firestore/example/test_driver/document_reference_e2e.dart
Outdated
Show resolved
Hide resolved
...d_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart
Outdated
Show resolved
Hide resolved
...tore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart
Outdated
Show resolved
Hide resolved
...tore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart
Outdated
Show resolved
Hide resolved
...tore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart
Show resolved
Hide resolved
...tore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart
Outdated
Show resolved
Hide resolved
...tore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart
Outdated
Show resolved
Hide resolved
...tore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart
Outdated
Show resolved
Hide resolved
...irestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart
Outdated
Show resolved
Hide resolved
.../cloud_firestore_platform_interface/test/method_channel_tests/method_channel_query_test.dart
Outdated
Show resolved
Hide resolved
hi @rrousselGit thank you for reviewing. The code has been updated & a major part of the review eliminated by deleting the code in question. ;-)). Please let me know if you have further comments. |
Providing @rrousselGit is happy with the feedback changes I'd like to get this merged today 🙃 After that we need to figure out a plan to fix the other plugins 🙈 |
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.
A test to verify that the stacktrace is passed correctly in the error streams would be awesome.
But otherwise LGTM
@rrousselGit I had a look at forwarding the stack in method_channel_document_reference, however it is empty on the source if you will:
outputs From scanning the native code, I can not see a way to push a custom stack trace either. Therefore I'd say we ignore it for now. |
Fair enough |
@Salakar I'm looking at firebase_auth currently - do let me know if there is another channel to discuss / coordinate. |
Drop me a mail and I can invite you to our internal slack if you'd like. mike [at] invertase.io |
any idea when this will be available on pub.dev? I'm excited to see if this fixes a lot of crashes |
Description
As discussed in #4108, the current implementation for query snapshots (or document snapshots) is not working well in a multi isolate environment due to a static reference to the
MethodChannel
that calls back from Native to Dart.This PR introduces a EventChannel per snapshot listener which works around this problem.
Related Issues
Closes #3671
Closes #4108
Closes #4267
Checklist
Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes (
[x]
).This will ensure a smooth and quick review process. Updating the
pubspec.yaml
and changelogs is not required.///
).flutter analyze
) does not report any problems on my PR.Breaking Change
Does your PR require plugin users to manually update their apps to accommodate your change?
Please help testing the PR
Add the following to your
pubspec.yaml
:Then run
flutter clean && flutter pub get
& test your iOS & Android Apps again.Good test scenarios:
flutter_workmanager
background_locator
plugin callbacks