I am trying to use firebase package to see if I can use it with my app | https://pub.dartlang.org/packages/firebase
I am trying to covert this code in Javascript
var upvotesRef = new Firebase('https://docs-examples.firebaseio.com/android/saving-data/fireblog/posts/-JRHTHaIs-jNPLXOQivY/upvotes');
upvotesRef.transaction(function (current_value) {
return (current_value || 0) + 1;
});
taken from https://www.firebase.com/docs/web/guide/saving-data.html#section-transactions
My attempt in dart is:
int getMrn() {
var testRef = firebaseClient.child('mrn');
return testRef.transaction((curVal) {
return curVal == null ? 1 : curVal + 1;
}).then((result) {
var snapshot = result.snapshot;
print( snapshot.val());
});
}
The correct curVal is returned and the mrn is written correctly to the database. Also the correct value is printed.
However, I get the following error and I am uncertain why:
Exception: Uncaught Error: type '_Future' is not a subtype of type 'int' of 'function result'.
Stack Trace:
#0 getMrn (package:epimss_db/firebase_db.dart:26:15)
#1 onMenuItemSelected (package:epimss_lab/components/chempath/nephrology/electrolytes_rqst_form.dart:116:17)
#2 Function.apply (dart:core-patch/function_patch.dart:28)
#3 GeneratedObjectAccessorService.invoke (package:smoke/static.dart:149:28)
#4 invoke (package:smoke/smoke.dart:43:41)
#5 HtmlElement&Polymer.dispatchMethod (package:polymer/src/instance.dart:1054:19)
#6 BindingDelegate&PolymerEventBindings.getEventHandler.<anonymous closure> (package:polymer/src/events.dart:82:32)
#7 _RootZone.runUnaryGuarded (dart:async/zone.dart:1093)
#8 _RootZone.bindUnaryCallback.<anonymous closure> (dart:async/zone.dart:1122)
#9 BindingDelegate&PolymerEventBindings.prepareEventBinding.<anonymous closure>.<anonymous closure> (package:polymer/src/events.dart:101:67)
#10 BlinkEventTarget.dispatchEvent_Callback_1 (dart:_blink:7764)
#11 BlinkEventTarget.dispatchEvent_Callback_1_ (dart:_blink:7765)
#12 EventTarget.dispatchEvent (dart:html:14741)
#13 onMainActionClicked (package:html_components/menu/split_button.dart:34:23)
#14 Function.apply (dart:core-patch/function_patch.dart:28)
#15 GeneratedObjectAccessorService.invoke (package:smoke/static.dart:149:28)
#16 invoke (package:smoke/smoke.dart:43:41)
#17 HtmlElement&Polymer.dispatchMethod (package:polymer/src/instance.dart:1054:19)
#18 BindingDelegate&PolymerEventBindings.getEventHandler.<anonymous closure> (package:polymer/src/events.dart:82:32)
#19 _RootZone.runUnaryGuarded (dart:async/zone.dart:1093)
#20 _RootZone.bindUnaryCallback.<anonymous closure> (dart:async/zone.dart:1122)
#21 BindingDelegate&PolymerEventBindings.prepareEventBinding.<anonymous closure>.<anonymous closure> (package:polymer/src/events.dart:101:67)
1
Thanks
Future<int> getMrn() { // <== 3
var testRef = firebaseClient.child('mrn');
return testRef.transaction((curVal) { // <== 2)
return curVal == null ? 1 : curVal + 1;
}).then((result) {
var snapshot = result.snapshot;
print( snapshot.val());
return result; // <== 1)
});
}
1) The value returned from the last chained then() is returned at 2)
3) Because this is async code a Future<int> is returned instead of int.
You call this code like
getMrn().then((result) {
// doSomething with the code here
});
or with await
void someFunc() async { // <== async necessary in order to be able to use await
var result = await getMrn();
}
Related
I have follow code. I need to handle Exception in it, but I can't do it. And can't understand the reason.
try {
print("aaa");
List<List<dynamic>> result =
await connection.query(sql).timeout(Duration(seconds: 120));
print('bbb');
if (result.isEmpty) {
sql = """ ... """;
await connection.query(sql);
} else {
int dbXmlId = result[0][0];
DateTime dbXMLDocDate = result[0][1];
if (dbXMLDocDate.isBefore(DateTime.parse(docDate!))) {
sql = """ ... """;
// print(sql);
await connection.query(sql);
sql = """ .... """;
currentJob['filesInserted']++;
await connection.query(sql);
} else {
sql = """ .... """;
await connection.query(sql);
}
}
} on PostgreSQLException catch (e) {
print('Exception during Insert in xml_files: $e');
exit(0);
} on SocketException catch (e) {
// пытаемся багу поймать
print('SocketException during Insert in xml_files: $e');
exit(0);
} on Exception catch (e) {
print('BaseException during Insert in xml_files: $e');
exit(0);
} catch (e) {
print("We should not reach this");
}
What I am getting on console:
aaa
Unhandled exception:
SocketException: Write failed (OS Error: An existing connection was forcibly closed by the remote host, errno = 10054), address = localhost, port = 51230
#0 _NativeSocket.write (dart:io-patch/socket_patch.dart:1182:34)
#1 _RawSocket.write (dart:io-patch/socket_patch.dart:1897:15)
#2 _Socket._write (dart:io-patch/socket_patch.dart:2334:18)
#3 _SocketStreamConsumer.write (dart:io-patch/socket_patch.dart:2082:26)
#4 _SocketStreamConsumer.addStream.<anonymous closure> (dart:io-patch/socket_patch.dart:2056:11)
#5 _RootZone.runUnaryGuarded (dart:async/zone.dart:1620:10)
#6 _BufferingStreamSubscription._sendData(dart:async/stream_impl.dart:341:11)
#7 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#8 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:733:19)
#9 _StreamController._add (dart:async/stream_controller.dart:607:7)
#10 _StreamController.add (dart:async/stream_controller.dart:554:5)
#11 _StreamSinkImpl.add (dart:io/io_sink.dart:136:17)
#12 _Socket.add (dart:io-patch/socket_patch.dart:2181:38)
#13 Query.sendExtended (package:postgres/src/query.dart:98:12)
#14 _PostgreSQLConnectionStateIdle.processQuery (package:postgres/src/connection_fsm.dart:214:9)
#15 _PostgreSQLConnectionStateIdle.awake (package:postgres/srcconnection_fsm.dart:200:14)
#16 _PostgreSQLExecutionContextMixin._enqueue (package:postgres/srcconnection.dart:516:67)
#17 _PostgreSQLExecutionContextMixin._query (package:postgres/srcconnection.dart:460:15)
#18 _PostgreSQLExecutionContextMixin.query (package:postgres/srcconnection.dart:427:7)
#19 insertOrUpdateXmlFiles (package:data_loader/Servicesftp_service.dart:499:53)
#20 scanUnpackedFolder (package:data_loader/Services/ftp_service.dart:360:11)
<asynchronous suspension>
#21 unpackArchive (package:data_loader/Services/ftp_service.dart:320:6)
<asynchronous suspension>
#22 downloadArchive (package:data_loader/Services/ftp_service.dart:281:7)
<asynchronous suspension>
#23 runFtpParsingOrOnlyUnpackArchives (package:data_loader/Services/ftp_service.dart:736:5)
<asynchronous suspension>
#24 choiceOfProcessingAction (package:data_loader/Services/ftp_service.dart:658:9)
<asynchronous suspension>
#25 startNewJob (package:data_loader/Services/ftp_service.dart:762:5)
<asynchronous suspension>
#26 main.<anonymous closure> (file:///D:/code/zakupki/data_loader/bin/data_loader.dart:61:9)
<asynchronous suspension>
#27 Alfred._incomingRequest (package:alfred/src/alfred.dart:345:15)
<asynchronous suspension>
#28 _QueuedFuture.execute (package:queue/src/dart_queue_base.dart:26:16)
<asynchronous suspension>
I am seeing on console: aaa but do not see bbb and try-catch do not handle an Exception between them.
Full code: https://gist.github.com/bubnenkoff/7377f735671aacd624371a14151856f4
Solved though chat so this is a resume:
There have been created an issue for this problem here: https://github.com/isoos/postgresql-dart/issues/23
Initial testing shows that it might be because the package are using a synchronously completer, which is really a great way to get a lot of potential issues if you read the official documentation: https://api.dart.dev/stable/2.15.1/dart-async/Completer/Completer.sync.html
If the Completer is changed to a normal asynchronously completer, it is possible to catch the exception from the question.
The issue might be solved in another way but the conclusion is that the problem (with not being able to catch the exceptions, not the exceptions themself) is very likely in the postgres package and should be fixed here.
I'm fetching coordinates from Firestore to fill my map with stores locations. The Google Map Marker needs a LatLng object (that takes two double as parameters) with the latitude and longitude of a point. But, for each increment, I get the following exception: type 'String' is not a subtype of type 'double' (verbose down below).
However, the points do appear on the map, which should mean that the values ARE of type double...
I used the following code to identify the latitude and longitude type:
if (store['latitude'] is double) {
print('double!');
} else if (store['latitude'] is String) {
print('string!');
}
print('');
if (store['longitude'] is double) {
print('double!');
} else if (store['longitude'] is String) {
print('string!');
}
print('');
It says "double!" each time.
Here is the code:
Firestore.instance
.collection('points-of-sale')
.snapshots()
.listen((data) => data.documents.forEach((store) {
LatLng pos = LatLng(
store['latitude'], // Here
store['longitude'] // and here
);
/* Adding a marker to the map */
}));
This is the full error:
[VERBOSE-2:ui_dart_state.cc(148)] Unhandled Exception: type 'String' is not a subtype of type 'double'
#0 _StoreLocatorState._addMarker (package:leonor_greyl_app_2019_41820/pages/StoreLocatorWidget.dart:21:30)
#1 _StoreLocatorState.build.<anonymous closure>.<anonymous closure> (package:leonor_greyl_app_2019_41820/pages/StoreLocatorWidget.dart:48:15)
#2 List.forEach (dart:core-patch/growable_array.dart:278:8)
#3 _StoreLocatorState.build.<anonymous closure> (package:leonor_greyl_app_2019_41820/pages/StoreLocatorWidget.dart:47:42)
#4 _rootRunUnary (dart:async/zone.dart:1132:38)
#5 _CustomZone.runUnary (dart:async/zone.dart:1029:19)
#6 _CustomZone.runUnaryGuarded (dart:async/zone.dart:931:7)
#7 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:336:11)
#8 _DelayedData.perform (dart:async/stream_impl.dart:591:14)
#9 _StreamImplEvents.handleNext (dart:async/stream_impl.dart:707:11)
#10 _PendingEvents.schedule.<anonymous closure> (dart:a<…>
EDIT:
This is the full verbose output for parseDouble(store['latitude']):
[VERBOSE-2:ui_dart_state.cc(148)] Unhandled Exception: FormatException: Invalid double
x
#0 double.parse (dart:core-patch/double_patch.dart:110:28)
#1 _StoreLocatorState._addMarker (package:leonor_greyl_app_2019_41820/pages/StoreLocatorWidget.dart:22:66)
#2 _StoreLocatorState.build.<anonymous closure>.<anonymous closure> (package:leonor_greyl_app_2019_41820/pages/StoreLocatorWidget.dart:51:15)
#3 List.forEach (dart:core-patch/growable_array.dart:278:8)
#4 _StoreLocatorState.build.<anonymous closure> (package:leonor_greyl_app_2019_41820/pages/StoreLocatorWidget.dart:50:42)
#5 _rootRunUnary (dart:async/zone.dart:1132:38)
#6 _CustomZone.runUnary (dart:async/zone.dart:1029:19)
#7 _CustomZone.runUnaryGuarded (dart:async/zone.dart:931:7)
#8 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:336:11)
#9 _DelayedData.perform (dart:async/stream_impl.dart:591:14)
#10 _StreamImplEvents.handleNext (dart:async/stream_impl.dart:707:11)
#11 _<…>
Use the parseDouble function that returns null if the Object provided can not be parsed to a double. You can then check if the values of the longitude and latitude are null before creating the marker.
Firestore.instance
.collection('points-of-sale')
.snapshots()
.listen((data) => data.documents.forEach((store) {
double latitude = parseDouble(store['latitude']);
double longitude = parseDouble(store['longitude']);
// Check if parser returns null for non-parsable string
if (latitude != null && longitude != null) {
LatLng pos = LatLng(latitude, longitude);
/* Adding a marker to the map */
}
}));
parse Function
double parseDouble(dynamic value) {
try {
if (value is String) {
return double.parse(value);
} else if (value is double) {
return value;
} else {
return 0.0;
}
} catch (e) {
// return null if double.parse fails
return null;
}
}
How to fix this error
[ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception:
FormatException: Unexpected end of input (at character 1) E/flutter
(11841): E/flutter (11841): ^ E/flutter (11841): E/flutter (11841):
0 _ChunkedJsonParser.fail (dart:convert/runtime/libconvert_patch.dart:1357:5) E/flutter (11841):
1 _ChunkedJsonParser.close (dart:convert/runtime/libconvert_patch.dart:510:7) E/flutter (11841):
2 _parseJson (dart:convert/runtime/libconvert_patch.dart:30:10) E/flutter (11841): #3 JsonDecoder.convert
(dart:convert/json.dart:491:36) E/flutter (11841): #4
JsonCodec.decode (dart:convert/json.dart:149:41) E/flutter (11841): #5
storeSync (package:reborn_next_job02/Cache/syncApi.dart:19:29)
E/flutter (11841): E/flutter (11841): #6
_ListPageState.initState. (package:reborn_next_job02/ui/AssetRegisters.dart:54:9) E/flutter
(11841): #7 _rootRunUnary (dart:async/zone.dart:1132:38)
E/flutter (11841): #8 _CustomZone.runUnary
(dart:async/zone.dart:1029:19) E/flutter (11841): #9
_CustomZone.runUnaryGuarded (dart:async/zone.dart:931:7) E/flutter (11841): #10 _CustomZone.bindUnaryCallbackGuarded. (dart:async/zone.dart:968:26) E/flutter (11841): #11
_rootRunUnary (dart:async/zone.dart:1136:13) E/flutter (11841): #12 _CustomZone.runUnary (dart:async/zone.dart:1029:19) E/flutter (11841): #13 _CustomZone.bindUnaryCallback. (dart:async/zone.dart:952:26) E/flutter (11841): #14
_Timer._runTimers (dart:isolate/runtime/libtimer_impl.dart:382:19) E/flutter (11841): #15 _Timer._handleMessage
(dart:isolate/runtime/libtimer_impl.dart:416:5) E/flutter (11841): #16
_RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:171:12)
syncApi.dart
storeSync(String url, String token) async {
final response = await http.get(
'$url/v1.0/SyncDataTable',
headers: {'Authorization': 'Bearer $token'},
);
final jsonResponse = json.decode(response.body);
SyncModel model = SyncModel.fromJson(jsonResponse);
int length = model.data.length;
HelperSync().display()).elementAt(i)?.syn_ChangeSequence,
for (int i = 0; i < length; i++) {
if ((await HelperSync().display()).elementAt(i)?.syn_TableName == model.data[i].syn_TableName) {
if ((await HelperSync().display()).elementAt(i)?.syn_ChangeSequence != model.data[i].syn_ChangeSequence) {
switch (i) {
case 21:
{
await HelperDatabase1().storeRegister(url, token);
}
break;
}
}
}
}
}
"FormatException" errors are usually caused by encoding issues. To solve this issue, you can cast response.body as a HashMap to look for the resulting Map<String, dynamic> before decoding.
// final jsonResponse = json.decode(response.body); // we can skip
SyncModel model = SyncModel.fromJson(response.body as Map<String, dynamic>>);
I am using Event Channels in Flutter to return beacon data from Native SDK to Flutter. This was working fine until a recent Flutter upgrade.Now, I am getting the following error.
type '(PlatformException) => void' is not a subtype of type '(Object) => FutureOr<dynamic>
with the following stack trace:
#0 _registerErrorHandler (dart:async/async_error.dart:22:60)
#1 _BufferingStreamSubscription.onError (dart:async/stream_impl.dart:146:16)
#2 new _BufferingStreamSubscription (dart:async/stream_impl.dart:113:10)
#3 new _ControllerSubscription (dart:async/stream_controller.dart)
#4 new _BroadcastSubscription (dart:async/broadcast_stream_controller.dart)
#5 _BroadcastStreamController._subscribe (dart:async/broadcast_stream_controller.dart:212:46)
#6 _ControllerStream._createSubscription (dart:async/stream_controller.dart:817:19)
#7 _StreamImpl.listen (dart:async/stream_impl.dart:466:9)
#8 _MyHomePageState.initPlatformState.<anonymous closure>.<anonymous closure> (file:///Users/chaythanyanair/Documents/Qburst/Learn/flutter_poc/lib/main.dart:95:43)
#9 _RootZone.runUnary (dart:async/zone.dart:1381:54)
#10 _FutureListener.handleValue (dart:async/future_impl.dart:129:18)
#11 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:633:45)
#12 Future._propagateToListeners (dart:async/future_impl.dart:662:32)
#13 Future._complete (dart:async/future_impl.dart:467:7)
#14 _SyncCompleter.complete (dart:async/future_impl.dart:51:12)
#15 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart)
<asynchronous suspension>
#16 _MyHomePageState.initPlatformState.<anonymous closure> (file:///Users/chaythanyanair/Documents/Qburst/Learn/flutter_poc/lib/main.dart:89:24)
<asynchronous suspension>
#17 _RootZone.runUnary (dart:async/zone.dart:1381:54)
#18 _FutureListener.handleValue (dart:async/future_impl.dart:129:18)
#19 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:633:45)
#20 Future._propagateToListeners (dart:async/future_impl.dart:662:32)
#21 Future._complete (dart:async/future_impl.dart:467:7)
#22 _SyncCompleter.complete (dart:async/future_impl.dart:51:12)
#23 User_Profile.getUser (package:flutter_poc/Models/User.dart)
<asynchronous suspension>
#24 _MyHomePageState.initPlatformState (file:///Users/chaythanyanair/Documents/Qburst/Learn/flutter_poc/lib/main.dart:69:24)
<asynchronous suspension>
#25 _MyHomePageState.initState (file:///Users/chaythanyanair/Documents/Qburst/Learn/flutter_poc/lib/main.dart:52:5)
#26 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:3734:58)
#27 ComponentElement.mount (package:flutter/src/widgets/framework.dart:3600:5)
#28 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2890:14)
#29 Element.updateChild
This is my EventChannel implementation:
static const platform = const MethodChannel('samples.flutter.io/initialiseRanging');
static const stream =
const EventChannel('samples.flutter.io/ranging');
try {
await platform.invokeMethod('initialiseRanging').then((result){
print(result);
setState(() {
_currentValue = result;
});
stream.receiveBroadcastStream().listen(_onEvent, onError: _onError);
});
} on PlatformException catch (e) {
print( "{e.message}");
}
This is how the _onEvent and _onError functions are implemented.
void _onEvent(Object event) {
setState(() {
_currentValue = event.toString();
});
print(event);
}
void _onError(PlatformException error) {
print(error);
}
Any idea on why this could possible happen?
void _onError(PlatformException error) {
should be
void _onError(Object error) {
Even when you are only interested in PlatformException or even when this is the only exception that happened so far, doesn't mean there can't be others. The expected handler function needs to match the parameter type, instead of only the exceptions you expect.
I have the following dart code:
.dart
Future<int> currentMrn( ) async {
var rootRef = await firebaseClient;
var mrnRef = await rootRef.child( 'ids/mrn' );
var event = await mrnRef.onValue.first;
DataSnapshot ss = event.snapshot;
return ss.val( );
}
Future<int> nextMrn( ) async {
int curMrn = 0;
var rootRef = await firebaseClient;
Future<int> futureMrn = currentMrn( );
futureMrn.then( ( int value ) {
if ( value == null ) {
rootRef.child('ids/mrn').set(curMrn);
//futureMrn = Future.value([curMrn]);
}
else {
curMrn = value + 1;
rootRef.child('ids/mrn').set(curMrn);
//futureMrn = Future.value([curMrn]);
}
} );
return currentMrn( );
}
The code is called as such:
.dart
nextMrn().then((int value) {
print(value);
});
However, the printed value is ALWAYS 1 less than the value in firebase.
It seems that currentMrn() is not getting the new updated value.
I am using the dart firebase package at https://pub.dartlang.org/packages/firebase
Thanks for your help.
EDIT 1
Running the future.then (first version) of nextMrn() throws the following exception
Exception: Uncaught Error: The null object does not have a method 'cancel'.
NoSuchMethodError: method not found: 'cancel'
Receiver: null
Arguments: []
Stack Trace:
#0 Object._noSuchMethod (dart:core-patch/object_patch.dart:42)
#1 Object.noSuchMethod (dart:core-patch/object_patch.dart:45)
#2 _cancelAndValue (dart:async/stream_pipe.dart:58)
#3 Stream.first.<anonymous closure> (dart:async/stream.dart:937)
#4 _RootZone.runUnaryGuarded (dart:async/zone.dart:1104)
#5 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341)
#6 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:270)
#7 _SyncBroadcastStreamController._sendData (dart:async/broadcast_stream_controller.dart:362)
#8 _BroadcastStreamController.add (dart:async/broadcast_stream_controller.dart:237)
#9 Query._createStream.addEvent (package:firebase/src/firebase.dart:531:12)
#10 JsObject._callMethod (dart:js:678)
#11 JsObject.callMethod (dart:js:618)
#12 Query._createStream.startListen (package:firebase/src/firebase.dart:539:11)
#13 _runGuarded (dart:async/stream_controller.dart:769)
#14 _BroadcastStreamController._subscribe (dart:async/broadcast_stream_controller.dart:199)
#15 _ControllerStream._createSubscription (dart:async/stream_controller.dart:787)
#16 _StreamImpl.listen (dart:async/stream_impl.dart:474)
#17 Stream.first (dart:async/stream.dart:935)
#18 currentMrn.<currentMrn_async_body> (package:epimss_shared/src/epimss_shared_db_client.dart:34:36)
#19 _RootZone.runUnary (dart:async/zone.dart:1166)
#20 _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:494)
#21 _Future._propagateToListeners (dart:async/future_impl.dart:577)
#22 _Future._completeWithValue (dart:async/future_impl.dart:368)
#23 _Future._asyncComplete.<anonymous closure> (dart:async/future_impl.dart:422)
#24 _microtaskLoop (dart:async/schedule_microtask.dart:43)
#25 _microtaskLoopEntry (dart:async/schedule_microtask.dart:52)
#26 _ScheduleImmediateHelper._handleMutation (dart:html:42529)
Line #18 above refers to the
var event = await mrnRef.onValue.first;
line in the currentMrn() method. Seems like an attempt is made to cancel an event. Not certain.
EDIT 2
Because all prior attempts returns an integer 1 less than is expected, I have included the code for currentMrn() directly in nextMrn() as follows:
Future<int> currentMrn( ) async {
var rootRef = await firebaseClient;
var mrnRef = await rootRef.child( 'ids/mrn' );
var event = await mrnRef.onValue.first;
DataSnapshot ss = event.snapshot;
return ss.val( );
}
Future<int> nextMrn( ) async {
var curMrn = 0;
var rootRef = await firebaseClient;
var mrnRef = await rootRef.child( 'ids/mrn' );
var event = await mrnRef.onValue.first;
DataSnapshot ss = event.snapshot;
var value = ss.val( );
if ( value == null ) {
curMrn += curMrn + 1;
rootRef.child( 'ids/mrn' ).set( curMrn );
}
else {
curMrn = value + 1;
rootRef.child( 'ids/mrn' ).set( curMrn );
}
return curMrn;
//TODO correct Bad state: Cannot fire new event. Controller is already firing an event
}
This correctly returns the expected value when nextMrn() is invoked. However, it throws the exception below:
FIREBASE WARNING: Exception was thrown by user callback.
Uncaught Unhandled exception:
Bad state: Cannot fire new event. Controller is already firing an event
#0 _BroadcastStreamController.add (dart:async/broadcast_stream_controller.dart:236)
#1 Query._createStream.addEvent (package:firebase/src/firebase.dart:531:12)
#2 JsObject._callMethod (dart:js:678)
#3 JsObject.callMethod (dart:js:618)
#4 Firebase.set (package:firebase/src/firebase.dart:258:9)
#5 nextMrn.<nextMrn_async_body> (package:epimss_shared/src/epimss_shared_db_client.dart:56:38)
#6 _RootZone.runUnary (dart:async/zone.dart:1166)
#7 _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:494)
#8 _Future._propagateToListeners (dart:async/future_impl.dart:577)
#9 _Future._complete (dart:async/future_impl.dart:358)
#10 _cancelAndValue (dart:async/stream_pipe.dart:62)
#11 Stream.first.<anonymous closure> (dart:async/stream.dart:937)
#12 _RootZone.runUnaryGuarded (dart:async/zone.dart:1104)
#13 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341)
#14 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:270)
#15 _SyncBroadcastStreamController._sendData (dart:async/broadcast_stream_controller.dart:362)
#16 _BroadcastStreamController.add (dart:async/broadcast_stream_controller.dart:237)
#17 Query._createStream.addEvent (package:firebase/src/firebase.dart:531:12)
(anonymous function)
that points to the following line in the refactored nextMrn()
rootRef.child( 'ids/mrn' ).set( curMrn );
Two questions:
1. How is this corrected.
2. How do I catch an error in the nextMrn()?
Thanks
Future<int> nextMrn( ) async {
int curMrn = 0;
var rootRef = await firebaseClient;
Future<int> futureMrn = currentMrn( );
// missing return leads to broken future chain
return futureMrn.then( ( int value ) {
if ( value == null ) {
rootRef.child('ids/mrn').set(curMrn);
//futureMrn = Future.value([curMrn]);
}
else {
curMrn = value + 1;
rootRef.child('ids/mrn').set(curMrn);
//futureMrn = Future.value([curMrn]);
}
// add the actual return in the chain to ensure
// id doesn't return before the calculation is completed
}).then((_) => currentMrn( );
}
or with async/await
Future<int> nextMrn( ) async {
int curMrn = 0;
var rootRef = await firebaseClient;
var futureMrn = currentMrn( );
var value = await futureMrn;
if ( value == null ) {
rootRef.child('ids/mrn').set(curMrn);
//futureMrn = Future.value([curMrn]);
}
else {
curMrn = value + 1;
rootRef.child('ids/mrn').set(curMrn);
//futureMrn = Future.value([curMrn]);
}
return currentMrn( );
}
I couldn't really figure out what exactly the intention of your code is. Hope it works anyway.