Skip to content
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

[cloud_firestore]: iOS includeMetadataChanges on document snapshots does not receive fromCache events correctly #12761

Closed
1 task done
PJakubec opened this issue May 9, 2024 · 1 comment · Fixed by #12764
Assignees
Labels
platform: ios Issues / PRs which are specifically for iOS. plugin: cloud_firestore resolution: fixed A fix has been merged or is pending merge from a PR. type: bug Something isn't working

Comments

@PJakubec
Copy link

PJakubec commented May 9, 2024

Is there an existing issue for this?

  • I have searched the existing issues.

Which plugins are affected?

Core, Cloud_Firestore

Which platforms are affected?

iOS

Description

On an iOS device, using includeMetadataChanges does not work correctly for single document snapshots (which works correctly for collection snapshots which was fixed in this week's commit #12739) for both:

  • First query execution
  • Regaining/Losing connection to the database

The following examples were tested on an iOS Simulator, but the same problem exists on real devices as well.
These examples compare the behavior of Collection snapshots (which work as expected) and Document snapshots (that behave unexpectedly).

Example: Collection Snapshot (works as expected)

final collectionRef = FirebaseFirestore.instance.collection('col');
colectionRef
  .snapshots(includeMetadataChanges: true)
  .listen((event) => print('FromCache: ${event.metadata.isFromCache}'));

Launching the app

When we launch the app, first we receive data from the cache and then we receive data from the database (as expected):

flutter: FromCache: true
flutter: FromCache: false

Regaining connection to DB

Process: After disconnecting the simulator from an internet connection, I will send a modification to the database. Then I will enable the internet connection.

final update = {'ts': DateTime.now().toIso8601String()};
collectionRef.doc('doc').update(update);

Received events (as expected):

flutter: FromCache: true // This event was received by disconnecting the internet connection
flutter: FromCache: true // Received by sending a modification
flutter: FromCache: false // Received when connected to the internet
flutter: FromCache: false // Received after all modifications have been written to DB

Example: Document Snapshot (incorrect behavior)

final documentRef = FirebaseFirestore.instance.collection('col').doc('doc');
documentRef
  .snapshots(includeMetadataChanges: true)
  .listen((event) => print('FromCache: ${event.metadata.isFromCache}'));

Launching the app (for the second time - the first time we don't have any data cached so we will receive the event fromCache: false)

When we launch the app, we receive data from the cache, but we do not receive the event from the server (which would be expected).

flutter: FromCache: true

The FromCache: false event is not received when the query is first executed, but it will be received only after data is updated in the database (or we send a modification from the app).

Regaining connection to DB
Process: After disconnecting the simulator from an internet connection, I will send a modification to the database. Then I will enable the internet connection.

final update = {'ts': DateTime.now().toIso8601String()};
collectionRef.doc('doc').update(update);

Received events:

flutter: FromCache: true // Event received after sending the modification

As opposed to Collection Reference, we did not receive the event fromCache: true after we lost the database connection. We also do not receive fromCache: false events after the connection is regained nor after all modifications are written.

We will receive the fromCache: false event only after the data in the database is updated which is not expected behavior.

Expected behavior:

Both single document snapshots and collection snapshots should behave consistently.

The correct behavior is of the collection snapshots.

Appendix:

This issue has already been reported once for collection snapshots: #12722.
The conclusion was a new ticket to ios sdk (firebase/firebase-ios-sdk#12869), where the solution was to change addSnapshotListenerWithOptions:options to addSnapshotListenerWithOptions:optionsWithSourceAndMetadata.
Thus a bug fix was pushed to flutterfire.

However going into the fix (#12739), I noticed that only file FLTQuerySnapshotStreamHandler.m was updated with this change, but file FLTDocumentSnapshotStreamHandler.m does not have these changes applied.

Reproducing the issue

Create a new Flutter app and connect it to Firebase. In this app, create a new listener that will observe document snapshots with metadata changes.

final documentRef = FirebaseFirestore.instance.collection('col').doc('doc');
documentsRef
  .snapshots(includeMetadataChanges: true)
  .listen((event) => print('FromCache: ${event.metadata.isFromCache}'));

Test both of these scenarios:

  • First query execution
  • Regaining/Losing connection to the database

An app I used for testing is available at:

https://github.com/TypeSoft-Ltd/firebase-metadata-changes-bug

To test different behavior between collection and document snapshots, change the useDocumentReference bool property to true and false on widget TestMetadataChangesPage in the app/widget/app_root.dart

Firebase Core version

2.31.0

Flutter Version

3.19.5

Relevant Log Output

No response

Flutter dependencies

Expand Flutter dependencies snippet
Dart SDK 3.3.3
Flutter SDK 3.19.5
firebase_metadata_changes 1.0.0+1

dependencies:
- cloud_firestore 4.17.3 [cloud_firestore_platform_interface cloud_firestore_web collection firebase_core firebase_core_platform_interface flutter meta]
- cupertino_icons 1.0.8
- firebase_core 2.31.0 [firebase_core_platform_interface firebase_core_web flutter meta]
- flutter 0.0.0 [characters collection material_color_utilities meta vector_math sky_engine]

dev dependencies:
- flutter_lints 3.0.2 [lints]
- flutter_test 0.0.0 [flutter test_api matcher path fake_async clock stack_trace vector_math leak_tracker_flutter_testing async boolean_selector characters collection leak_tracker leak_tracker_testing material_color_utilities meta source_span stream_channel string_scanner term_glyph vm_service]

transitive dependencies:
- _flutterfire_internals 1.3.33 [collection firebase_core firebase_core_platform_interface flutter meta]
- async 2.11.0 [collection meta]
- boolean_selector 2.1.1 [source_span string_scanner]
- characters 1.3.0
- clock 1.1.1
- cloud_firestore_platform_interface 6.2.3 [_flutterfire_internals collection firebase_core flutter meta plugin_platform_interface]
- cloud_firestore_web 3.12.3 [_flutterfire_internals cloud_firestore_platform_interface collection firebase_core firebase_core_web flutter flutter_web_plugins]
- collection 1.18.0
- fake_async 1.3.1 [clock collection]
- firebase_core_platform_interface 5.0.0 [collection flutter flutter_test meta plugin_platform_interface]
- firebase_core_web 2.17.0 [firebase_core_platform_interface flutter flutter_web_plugins meta web]
- flutter_web_plugins 0.0.0 [flutter characters collection material_color_utilities meta vector_math]
- leak_tracker 10.0.0 [clock collection meta path vm_service]
- leak_tracker_flutter_testing 2.0.1 [flutter leak_tracker leak_tracker_testing matcher meta]
- leak_tracker_testing 2.0.1 [leak_tracker matcher meta]
- lints 3.0.0
- matcher 0.12.16+1 [async meta stack_trace term_glyph test_api]
- material_color_utilities 0.8.0 [collection]
- meta 1.11.0
- path 1.9.0
- plugin_platform_interface 2.1.8 [meta]
- sky_engine 0.0.99
- source_span 1.10.0 [collection path term_glyph]
- stack_trace 1.11.1 [path]
- stream_channel 2.1.2 [async]
- string_scanner 1.2.0 [source_span]
- term_glyph 1.2.1
- test_api 0.6.1 [async boolean_selector collection meta source_span stack_trace stream_channel string_scanner term_glyph]
- vector_math 2.1.4
- vm_service 13.0.0
- web 0.5.1
Expand flutter doctor -v snippet
[✓] Flutter (Channel stable, 3.19.5, on macOS 14.0 23A344 darwin-arm64, locale en-CZ)
    • Flutter version 3.19.5 on channel stable at /Users/pavel/fvm/versions/3.19.5
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 300451adae (6 weeks ago), 2024-03-27 21:54:07 -0500
    • Engine revision e76c956498
    • Dart version 3.3.3
    • DevTools version 2.31.1

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    • Android SDK at /Users/pavel/Library/Android/sdk
    • Platform android-34, build-tools 34.0.0
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.9+0-17.0.9b1087.7-11185874)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 15.0)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 15A240d
    • CocoaPods version 1.15.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2023.2)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 17.0.9+0-17.0.9b1087.7-11185874)

[✓] VS Code (version 1.89.0)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.88.0

[✓] Connected device (4 available)
    • sdk gphone64 arm64 (mobile) • emulator-5554                        • android-arm64  • Android 13 (API 33)
      (emulator)
    • iPhone 15 Pro Max (mobile)  • 41E888F5-2E90-412D-89AA-89D1409FFF49 • ios            •
      com.apple.CoreSimulator.SimRuntime.iOS-17-0 (simulator)
    • macOS (desktop)             • macos                                • darwin-arm64   • macOS 14.0 23A344
      darwin-arm64
    • Chrome (web)                • chrome                               • web-javascript • Google Chrome 124.0.6367.119
    ! Error: Browsing on the local area network for Development’s iPhone. Ensure the device is unlocked and attached
      with a cable or associated with the same local area network as this Mac.
      The device must be opted into Developer Mode to connect wirelessly. (code -27)

[✓] Network resources
    • All expected network resources are available.

• No issues found!

Additional context and comments

No response

@TarekkMA
Copy link
Contributor

TarekkMA commented May 9, 2024

@PJakubec Thank you for reporting this issue. I will look into solving this issue.

@TarekkMA TarekkMA added plugin: cloud_firestore platform: ios Issues / PRs which are specifically for iOS. and removed Needs Attention This issue needs maintainer attention. labels May 9, 2024
@TarekkMA TarekkMA self-assigned this May 9, 2024
@TarekkMA TarekkMA added the resolution: fixed A fix has been merged or is pending merge from a PR. label May 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment