Flutterfire: ๐Ÿ› [cloud_firestore] [web] Unexpected return from a transaction causes cryptic runtime error.

Created on 9 Sep 2020  ยท  10Comments  ยท  Source: FirebaseExtended/flutterfire

Bug report

Steps to reproduce

The following code:

Future<void> addReview({String restaurantId, Review review}) {
  final restaurant = FirebaseFirestore.instance.collection('restaurants').doc(restaurantId);
  final newReview = restaurant.collection('ratings').doc();

  return FirebaseFirestore.instance.runTransaction((Transaction transaction) {
    return transaction
        .get(restaurant)
        .then((DocumentSnapshot doc) => Restaurant.fromSnapshot(doc))
        .then((Restaurant fresh) {

      // [...]
      return transaction.set(newReview, {
        // data
      });

    });
  });
}

Causes a somewhat cryptic error:

Error: [cloud_firestore/unknown] Invalid argument (dartObject): Could not convert: Instance of 'Transaction'
    at Object.throw_ [as throw] (http://localhost:42399/dart_sdk.js:4332:11)
    at cloud_firestore_web.FirebaseFirestoreWeb.new.runTransaction (http://localhost:42399/packages/cloud_firestore_web/src/write_batch_web.dart.lib.js:719:21)
    at runTransaction.throw (<anonymous>)
    at http://localhost:42399/dart_sdk.js:37603:38
    at _RootZone.runBinary (http://localhost:42399/dart_sdk.js:37456:58)
    at _FutureListener.thenAwait.handleError (http://localhost:42399/dart_sdk.js:32440:48)
    at handleError (http://localhost:42399/dart_sdk.js:32991:51)
    at Function._propagateToListeners (http://localhost:42399/dart_sdk.js:33017:17)
    at _Future.new.[_completeError] (http://localhost:42399/dart_sdk.js:32864:23)
    at http://localhost:42399/dart_sdk.js:33087:38
    at _RootZone.runBinary (http://localhost:42399/dart_sdk.js:37456:58)
    at _FutureListener.then.handleError (http://localhost:42399/dart_sdk.js:32440:48)
    at handleError (http://localhost:42399/dart_sdk.js:32991:51)
    at Function._propagateToListeners (http://localhost:42399/dart_sdk.js:33017:17)
    at _Future.new.[_completeError] (http://localhost:42399/dart_sdk.js:32864:23)
    at async._AsyncCallbackEntry.new.callback (http://localhost:42399/dart_sdk.js:32902:31)
    at Object._microtaskLoop (http://localhost:42399/dart_sdk.js:37712:13)
    at _startMicrotaskLoop (http://localhost:42399/dart_sdk.js:37718:13)
    at http://localhost:42399/dart_sdk.js:33230:9

The problem is that return transaction.set(doc, data); in web the return shouldn't be there. I guess this is expected because the code expects a Future<void> but we're returning a Future<Transaction>, but... Is there any way of warning the user that they're messing up?

The error (web only, btw) is a little bit hard to track.

Expected behavior

Can this be detected at compile time, or make the error more clear? (I know this might be related to js-interop, though)


Flutter doctor

Run flutter doctor and paste the output below:

Click To Expand

$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[โœ“] Flutter (Channel master, 1.22.0-10.0.pre.28, on Linux, locale en_US.UTF-8)
[โœ“] Android toolchain - develop for Android devices (Android SDK version 29.0.1)
[โœ“] Chrome - develop for the web
[!] Android Studio (version 3.4)
    โœ— Unable to find bundled Java version.
[โœ“] Android Studio (version 3.5)
[โœ“] VS Code (version 1.47.3)
[โœ“] Connected device (2 available)


Flutter dependencies

Run flutter pub deps -- --style=compact and paste the output below:

Click To Expand

Dart SDK 2.10.0-76.0.dev
Flutter SDK 1.22.0-10.0.pre.28
friendlyeats 0.0.0

dependencies:
- cloud_firestore 0.14.0+2 [flutter meta quiver firebase_core firebase_core_platform_interface cloud_firestore_platform_interface cloud_firestore_web]
- firebase_auth 0.18.0+1 [meta firebase_core firebase_core_platform_interface firebase_auth_platform_interface firebase_auth_web flutter]
- firebase_core 0.5.0 [firebase_core_platform_interface flutter quiver meta firebase_core_web]
- flutter 0.0.0 [characters collection meta typed_data vector_math sky_engine]
- responsive_grid 1.2.1+1 [flutter]
- sliver_fab 1.0.0 [flutter]
- smooth_star_rating 1.1.1 [flutter]

dev dependencies:
- flutter_test 0.0.0 [flutter test_api path fake_async clock stack_trace vector_math async boolean_selector characters charcode collection matcher meta source_span stream_channel string_scanner term_glyph typed_data]
- pedantic 1.9.0

transitive dependencies:
- async 2.5.0-nullsafety [collection]
- boolean_selector 2.1.0-nullsafety [source_span string_scanner]
- characters 1.1.0-nullsafety.2
- charcode 1.2.0-nullsafety
- clock 1.1.0-nullsafety
- cloud_firestore_platform_interface 2.0.1 [flutter meta collection firebase_core plugin_platform_interface]
- cloud_firestore_web 0.2.0+1 [flutter flutter_web_plugins firebase http_parser meta firebase_core cloud_firestore_platform_interface js]
- collection 1.15.0-nullsafety.2
- fake_async 1.1.0-nullsafety [clock collection]
- firebase 7.3.0 [http http_parser js]
- firebase_auth_platform_interface 2.0.1 [flutter meta firebase_core plugin_platform_interface]
- firebase_auth_web 0.3.0+1 [flutter flutter_web_plugins firebase meta http_parser intl firebase_core firebase_auth_platform_interface js]
- firebase_core_platform_interface 2.0.0 [flutter meta plugin_platform_interface quiver]
- firebase_core_web 0.2.0 [firebase firebase_core_platform_interface flutter flutter_web_plugins meta js]
- flutter_web_plugins 0.0.0 [flutter characters collection meta typed_data vector_math]
- http 0.12.0+3 [async http_parser path pedantic]
- http_parser 3.1.3 [charcode collection source_span string_scanner typed_data]
- intl 0.16.1 [path]
- js 0.6.1+1
- matcher 0.12.10-nullsafety [stack_trace]
- meta 1.3.0-nullsafety.2
- path 1.8.0-nullsafety
- plugin_platform_interface 1.0.2 [meta]
- quiver 2.0.5 [matcher meta]
- sky_engine 0.0.99
- source_span 1.8.0-nullsafety [charcode collection path term_glyph]
- stack_trace 1.10.0-nullsafety [path]
- stream_channel 2.1.0-nullsafety [async]
- string_scanner 1.1.0-nullsafety [charcode source_span]
- term_glyph 1.2.0-nullsafety
- test_api 0.2.19-nullsafety [async boolean_selector collection meta path source_span stack_trace stream_channel string_scanner term_glyph matcher]
- typed_data 1.3.0-nullsafety.2 [collection]
- vector_math 2.1.0-nullsafety.2


cloud_firestore bug

All 10 comments

Hi @ditman.

I've attempted to recreate through a test case (see PR below)

This will correctly result in a build error for iOS.

Failed to build iOS app
Error output from Xcode build:
โ†ณ
* BUILD FAILED *

Xcode's output:
โ†ณ
test_driver/transaction_e2e.dart:112:46: Error: A value of type 'Transaction' can't be assigned to a variable of type
'FutureOr>'.
- 'Transaction' is from 'package:cloud_firestore/cloud_firestore.dart' ('../lib/cloud_firestore.dart').
- 'Future' is from 'dart:async'.
return transaction.set(newRef, {

Could this potentially mean there is a problem upstream with the web SDK? At this stage i'm not too sure how to recreate as web specific through testing.

Would it also be possible confirm which version of the web SDK in use?

For example

<script src="https://www.gstatic.com/firebasejs/7.14.4/firebase-app.js"></script>

Thanks for taking a look, I'll give this a shot. I'll try to run your test in web. Are you running it with flutter drive?

Yes flutter drive to run the tests in cloud_firestore.

Running an example project, I come accross the following...


NativeJavaScriptObject (FirebaseError: [code=unknown]: Server responded with status 403)
<error>:<getObject: Unsupported operation: unknown library: null>

This comes from the method chain...

Future get(DocumentReference documentRef) =>
handleThenable(jsObject.get(documentRef.jsObject)) <----Error
.then(DocumentSnapshot.getInstance);

getFirebaseException

 } on FirebaseException catch (ex) {
      print('Found errors >>>> ${ex}');
    }

Produces

Expected a value of type 'FirebaseError', but got one of type 'FirebaseException'

Hmm, looks like a different error that I was seeing, though :/

Hi @ditman

We have managed to successfully replicate the issue locally.

Continuing to debug to find the source of the issue.

Thanks for digging @dackers86!

Was this page helpful?
0 / 5 - 0 ratings