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.
Can this be detected at compile time, or make the error more clear? (I know this might be related to js-interop, though)
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)
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
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.
Investigation PR at https://github.com/FirebaseExtended/flutterfire/pull/3579
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
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!