When listening to a Firestore collection and calling a function with List<DocumentSnapshot> argument in a separate isolate leads to memory leak. When function argument is changed to int for example, there is no memory leak.
Memory leak when argument is List<DocumentSnapshot>:
firestore.collection('`myCollection').snapshots().listen(
(querySnapshot) {
compute(functionWithDocsArg, querySnapshot.docs);
},
);
int functionWithDocsArg(List<DocumentSnapshot> docs) {
debugPrint("DateTime.now():");
debugPrint(DateTime.now().toString());
debugPrint('functionWithDocsArg computed!');
return 0;
}
No memory leak when function is argument is different than List<DocumentSnapshot> for example int:
firestore.collection('`myCollection').snapshots().listen(
(querySnapshot) {
compute(functionWithIntArg, 33);
},
);
int functionWithIntArg(int x) {
debugPrint("DateTime.now():");
debugPrint(DateTime.now().toString());
debugPrint('functionWithIntArg computed!');
return 0;
}
There should be no memory leak.
Interestingly, even with functionWithIntArg, the memory is not released until the next computation fired.
Run flutter doctor and paste the output below:
Click To Expand
[√] Flutter (Channel stable, 1.22.3, on Microsoft Windows [Version 10.0.19041.630], locale tr-TR)
[√] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
[!] Android Studio (version 4.1.0)
X Flutter plugin not installed; this adds Flutter specific functionality.
X Dart plugin not installed; this adds Dart specific functionality.
[!] VS Code (version 1.51.1)
X Flutter extension not installed; install from
https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter
[√] Connected device (1 available)
! Doctor found issues in 2 categories.
Run flutter pub deps -- --style=compact and paste the output below:
Click To Expand
Dart SDK 2.10.3
Flutter SDK 1.22.3
dependencies:
- ads 2.1.1 [flutter firebase_admob]
- analyzer 0.39.17 [_fe_analyzer_shared args charcode cli_util collection convert crypto glob html meta package_config path pub_semver source_span watcher yaml]
- app_review 2.0.1 [http intl package_info url_launcher flutter]
- apple_sign_in 0.1.0 [flutter]
- auth 7.2.0 [flutter firebase_core firebase_auth google_sign_in google_sign_in_platform_interface flutter_login_facebook flutter_twitter]
- auto_size_text 2.1.0 [flutter]
- basics 0.4.0+1 [quiver]
- built_value 7.1.0 [built_collection collection fixnum quiver]
- cached_network_image 2.3.3 [flutter flutter_cache_manager octo_image]
- catcher 0.3.22 [flutter flutter_web_plugins fluttertoast device_info package_info mailer dio flutter_mailer logging sentry]
- characters 1.1.0-nullsafety.3
- cloud_firestore 0.14.3 [flutter meta quiver firebase_core firebase_core_platform_interface cloud_firestore_platform_interface cloud_firestore_web]
- cloud_functions 0.7.0+1 [meta flutter firebase_core firebase_core_platform_interface cloud_functions_platform_interface cloud_functions_web]
- condition 0.0.8 [flutter]
- csv 4.1.0
- cupertino_icons 1.0.0
- dartx 0.5.0 [collection path crypto characters time meta]
- deep_pick 0.5.1
- diacritic 0.1.1
- dio 3.0.10 [http_parser path]
- dio_http_cache 0.2.11 [flutter quiver json_serializable json_annotation dio sqflite path crypto]
- easy_localization 2.3.3 [flutter intl shared_preferences args path flutter_localizations]
- edit_distance 0.4.1
- firebase_analytics 6.2.0 [meta flutter firebase_core firebase_analytics_web firebase_analytics_platform_interface]
- firebase_auth 0.18.3 [meta firebase_core firebase_core_platform_interface firebase_auth_platform_interface firebase_auth_web flutter]
- firebase_core 0.5.2 [firebase_core_platform_interface flutter quiver meta firebase_core_web]
- firebase_crashlytics 0.2.3 [flutter stack_trace firebase_core firebase_core_platform_interface firebase_crashlytics_platform_interface]
- firebase_dynamic_links 0.6.2 [flutter firebase_core]
- firebase_messaging 7.0.3 [meta flutter firebase_core]
- flutter 0.0.0 [characters collection meta typed_data vector_math sky_engine]
- flutter_icons 1.1.0 [flutter]
- flutter_localizations 0.0.0 [flutter intl characters collection meta path typed_data vector_math]
- flutter_mobx 1.1.0+2 [mobx flutter]
- flutter_mobx_helpers 1.0.1 [mobx flutter]
- flutter_native_timezone 1.0.4 [flutter]
- flutter_platform_widgets 0.71.0 [flutter]
- flutter_secure_storage 3.3.5 [meta flutter]
- flutter_svg 0.19.1 [flutter meta path_drawing vector_math xml]
- google_fonts 1.1.1 [flutter http path_provider crypto pedantic]
- hive 1.4.4+1 [meta crypto]
- hive_flutter 0.3.1 [flutter hive path_provider path]
- mobx 1.2.1+4 [meta]
- mobx_codegen 1.1.2 [analyzer build build_resolvers meta mobx path source_gen]
- provider 4.3.2+2 [flutter nested collection]
- purchases_flutter 1.4.3 [flutter]
- sailor 0.7.1 [flutter]
- share 0.6.5+4 [meta mime flutter]
- stream_transform 1.2.0
- table_calendar 2.3.0 [flutter intl simple_gesture_detector]
- table_sticky_headers 1.2.0 [flutter]
dev dependencies:
- build_runner 1.10.2 [args async build build_config build_daemon build_resolvers build_runner_core code_builder collection crypto dart_style glob graphs http_multi_server io js logging
meta mime path pedantic pool pub_semver pubspec_parse shelf shelf_web_socket stack_trace stream_transform timing watcher web_socket_channel yaml]
- built_value_generator 7.1.0 [analyzer build build_config built_collection built_value source_gen quiver]
- effective_dart 1.3.0
- flutter_driver 0.0.0 [file json_rpc_2 meta path web_socket_channel vm_service_client webdriver flutter flutter_test fuchsia_remote_debug_protocol archive args async boolean_selector ch
aracters charcode clock collection convert crypto fake_async matcher platform process pub_semver source_span stack_trace stream_channel string_scanner sync_http term_glyph test_api typed
_data vector_math]
- flutter_launcher_icons 0.8.1 [image args yaml path]
- 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]
- test 1.16.0-nullsafety.5 [analyzer async boolean_selector coverage http http_multi_server io js node_preamble package_config path pedantic pool shelf shelf_packages_handler shelf_stati
c shelf_web_socket source_span stack_trace stream_channel typed_data web_socket_channel webkit_inspection_protocol yaml test_api test_core]
transitive dependencies:
- _fe_analyzer_shared 7.0.0 [meta]
- archive 2.0.13 [crypto args path]
- args 1.6.0
- async 2.5.0-nullsafety.1 [collection]
- boolean_selector 2.1.0-nullsafety.1 [source_span string_scanner]
- build 1.3.0 [analyzer async convert crypto logging meta path glob]
- build_config 0.4.2 [checked_yaml json_annotation meta path pubspec_parse yaml]
- build_daemon 2.1.4 [built_collection built_value http_multi_server logging pedantic path pool shelf shelf_web_socket stream_transform watcher web_socket_channel]
- build_resolvers 1.3.11 [analyzer build crypto graphs logging path package_config pub_semver]
- build_runner_core 6.0.1 [async build build_config build_resolvers collection convert crypto glob graphs json_annotation logging meta path package_config pedantic pool timing watcher ya
ml]
- built_collection 4.3.2 [collection quiver]
- charcode 1.2.0-nullsafety.1
- checked_yaml 1.0.2 [json_annotation source_span yaml]
- cli_util 0.2.0 [path]
- clock 1.1.0-nullsafety.1
- cloud_firestore_platform_interface 2.2.0 [flutter meta collection firebase_core plugin_platform_interface]
- cloud_firestore_web 0.2.1 [flutter flutter_web_plugins http_parser meta firebase_core firebase_core_web cloud_firestore_platform_interface js]
- cloud_functions_platform_interface 3.0.1 [flutter meta firebase_core plugin_platform_interface]
- cloud_functions_web 3.0.1 [firebase_core cloud_functions_platform_interface flutter flutter_web_plugins firebase http_parser meta]
- code_builder 3.5.0 [built_collection built_value collection matcher meta]
- collection 1.15.0-nullsafety.3
- convert 2.1.1 [charcode typed_data]
- coverage 0.14.2 [args logging package_config path source_maps stack_trace vm_service]
- crypto 2.1.5 [collection convert typed_data]
- csslib 0.16.2 [source_span]
- dart_style 1.3.6 [analyzer args path source_span]
- device_info 0.4.2+10 [flutter device_info_platform_interface]
- device_info_platform_interface 1.0.1 [flutter meta plugin_platform_interface]
- fake_async 1.2.0-nullsafety.1 [clock collection]
- ffi 0.1.3
- file 6.0.0-nullsafety.2 [meta path]
- firebase 7.3.2 [http http_parser js]
- firebase_admob 0.10.2 [meta flutter firebase_core]
- firebase_analytics_platform_interface 1.0.3 [flutter meta]
- firebase_analytics_web 0.1.1 [flutter flutter_web_plugins firebase firebase_analytics_platform_interface meta]
- firebase_auth_platform_interface 2.1.3 [flutter meta firebase_core plugin_platform_interface]
- firebase_auth_web 0.3.2 [flutter flutter_web_plugins meta http_parser intl firebase_core firebase_core_web firebase_auth_platform_interface js]
- firebase_core_platform_interface 2.0.0 [flutter meta plugin_platform_interface quiver]
- firebase_core_web 0.2.1 [firebase_core_platform_interface flutter flutter_web_plugins meta js]
- firebase_crashlytics_platform_interface 1.1.3 [flutter meta collection firebase_core plugin_platform_interface]
- fixnum 0.10.11
- flutter_blurhash 0.5.0 [flutter meta]
- flutter_cache_manager 2.0.0 [flutter path_provider uuid http path sqflite pedantic clock file rxdart]
- flutter_login_facebook 0.2.1+1 [flutter list_ext]
- flutter_mailer 1.0.1 [flutter]
- flutter_twitter 1.1.3 [flutter]
- flutter_web_plugins 0.0.0 [flutter characters collection meta typed_data vector_math]
- fluttertoast 7.1.1 [flutter flutter_web_plugins]
- fuchsia_remote_debug_protocol 0.0.0 [json_rpc_2 process web_socket_channel flutter_test flutter_driver archive args async boolean_selector charcode clock collection convert crypto fake
_async file matcher meta path platform pub_semver source_span stack_trace stream_channel string_scanner sync_http term_glyph test_api typed_data vector_math vm_service_client webdriver]
- glob 1.2.0 [async collection node_io path pedantic string_scanner]
- google_sign_in 4.5.6 [google_sign_in_platform_interface flutter meta google_sign_in_web]
- google_sign_in_platform_interface 1.1.2 [flutter meta quiver]
- google_sign_in_web 0.9.2 [google_sign_in_platform_interface flutter flutter_web_plugins meta js]
- graphs 0.2.0
- html 0.14.0+4 [csslib source_span]
- http 0.12.2 [http_parser path pedantic]
- http_multi_server 2.2.0 [async]
- http_parser 3.1.4 [charcode collection source_span string_scanner typed_data]
- image 2.1.19 [archive xml meta]
- intl 0.16.1 [path]
- io 0.3.4 [charcode meta path string_scanner]
- js 0.6.3-nullsafety.2
- json_annotation 3.1.0
- json_rpc_2 2.2.2 [stack_trace stream_channel]
- json_serializable 3.5.0 [analyzer build build_config json_annotation meta path source_gen]
- list_ext 0.1.14 [quiver collection]
- logging 0.11.4
- mailer 3.2.1 [async logging intl mime path pedantic]
- matcher 0.12.10-nullsafety.1 [stack_trace]
- meta 1.3.0-nullsafety.3
- mime 0.9.7
- nested 0.0.4 [flutter]
- node_interop 1.2.0 [js]
- node_io 1.1.1 [node_interop path]
- node_preamble 1.4.12
- octo_image 0.3.0 [flutter flutter_blurhash]
- package_config 1.9.3 [path charcode]
- package_info 0.4.3+2 [flutter]
- path 1.8.0-nullsafety.1
- path_drawing 0.4.1+1 [vector_math meta path_parsing flutter]
- path_parsing 0.1.4 [vector_math meta]
- path_provider 1.6.24 [flutter path_provider_platform_interface path_provider_macos path_provider_linux path_provider_windows]
- path_provider_linux 0.0.1+2 [path xdg_directories path_provider_platform_interface flutter]
- path_provider_macos 0.0.4+6 [flutter]
- path_provider_platform_interface 1.0.4 [flutter meta platform plugin_platform_interface]
- path_provider_windows 0.0.4+3 [path_provider_platform_interface meta path flutter ffi win32]
- pedantic 1.10.0-nullsafety.2
- petitparser 3.1.0 [meta]
- platform 3.0.0-nullsafety.2
- plugin_platform_interface 1.0.3 [meta]
- pool 1.5.0-nullsafety.2 [async stack_trace]
- process 4.0.0-nullsafety.2 [file path platform]
- pub_semver 1.4.4 [collection]
- pubspec_parse 0.1.5 [checked_yaml json_annotation pub_semver yaml]
- quiver 2.1.5 [matcher meta]
- rxdart 0.24.1
- sentry 3.0.1 [http meta stack_trace usage pedantic]
- shared_preferences 0.5.12+4 [meta flutter shared_preferences_platform_interface shared_preferences_linux shared_preferences_macos shared_preferences_web shared_preferences_windows]
- shared_preferences_linux 0.0.2+4 [file flutter meta path path_provider_linux shared_preferences_platform_interface]
- shared_preferences_macos 0.0.1+11 [shared_preferences_platform_interface flutter]
- shared_preferences_platform_interface 1.0.4 [meta flutter]
- shared_preferences_web 0.1.2+7 [shared_preferences_platform_interface flutter flutter_web_plugins meta]
- shared_preferences_windows 0.0.1+3 [shared_preferences_platform_interface flutter ffi file meta path path_provider_platform_interface path_provider_windows]
- shelf 0.7.9 [async collection http_parser path stack_trace stream_channel]
- shelf_packages_handler 2.0.0 [path shelf shelf_static]
- shelf_static 0.2.8 [convert http_parser mime path shelf]
- shelf_web_socket 0.2.3 [shelf web_socket_channel stream_channel]
- simple_gesture_detector 0.1.4 [flutter]
- sky_engine 0.0.99
- source_gen 0.9.7+1 [analyzer async build dart_style glob meta path pedantic source_span]
- source_map_stack_trace 2.1.0-nullsafety.3 [path stack_trace source_maps]
- source_maps 0.10.10-nullsafety.2 [source_span]
- source_span 1.8.0-nullsafety.2 [charcode collection path term_glyph]
- sqflite 1.3.2+1 [flutter sqflite_common path]
- sqflite_common 1.0.2+1 [synchronized path meta]
- stack_trace 1.10.0-nullsafety.1 [path]
- stream_channel 2.1.0-nullsafety.1 [async]
- string_scanner 1.1.0-nullsafety.1 [charcode source_span]
- sync_http 0.2.0
- synchronized 2.2.0+2
- term_glyph 1.2.0-nullsafety.1
- test_api 0.2.19-nullsafety.2 [async boolean_selector collection meta path source_span stack_trace stream_channel string_scanner term_glyph matcher]
- test_core 0.3.12-nullsafety.5 [analyzer async args boolean_selector collection coverage glob io meta package_config path pedantic pool source_map_stack_trace source_maps source_span st
ack_trace stream_channel vm_service yaml matcher test_api]
- time 1.3.0
- timing 0.1.1+2 [json_annotation]
- typed_data 1.3.0-nullsafety.3 [collection]
- url_launcher 5.7.10 [flutter url_launcher_platform_interface url_launcher_web url_launcher_linux url_launcher_macos url_launcher_windows]
- url_launcher_linux 0.0.1+4 [flutter]
- url_launcher_macos 0.0.1+9 [flutter]
- url_launcher_platform_interface 1.0.9 [flutter meta plugin_platform_interface]
- url_launcher_web 0.1.5+1 [url_launcher_platform_interface flutter flutter_web_plugins meta]
- url_launcher_windows 0.0.1+3 [flutter]
- usage 3.4.2 [path]
- uuid 2.2.2 [crypto convert]
- vector_math 2.1.0-nullsafety.3
- vm_service 5.5.0 [meta]
- vm_service_client 0.2.6+2 [async collection json_rpc_2 pub_semver source_span stack_trace stream_channel web_socket_channel]
- watcher 0.9.7+15 [async path pedantic]
- web_socket_channel 1.1.0 [async crypto stream_channel]
- webdriver 2.1.2 [archive matcher path stack_trace sync_http]
- webkit_inspection_protocol 0.7.4 [logging]
- win32 1.7.3 [ffi]
- xdg_directories 0.1.2 [meta path process]
- xml 4.5.1 [collection convert meta petitparser]
- yaml 2.2.1 [charcode collection string_scanner source_span]
Hi @deadsoul44
Could you please provide a minimal complete reproducible code sample?
Thank you
I tried to write a test but failed.
import 'dart:async';
import 'dart:math';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart';
import './mock.dart';
void main() {
setupCloudFirestoreMocks();
FirebaseFirestore firestore;
FirebaseFirestore firestoreSecondary;
MethodChannelFirebaseFirestore.channel.setMockMethodCallHandler((call) async {
String path = call.arguments['path'];
if (call.method == 'DocumentReference#get' && path == 'doc/exists') {
return {
'data': {
'foo': 'bar',
},
'metadata': {
'hasPendingWrites': true,
'isFromCache': true,
}
};
}
if (call.method == 'DocumentReference#set') {
return {
'data': {
'foo': 'bar',
},
};
}
return null;
});
Timer timer;
Random random;
group("$CollectionReference", () {
setUpAll(() async {
await Firebase.initializeApp();
var secondaryApp = await Firebase.initializeApp(
name: 'foo',
options: FirebaseOptions(
apiKey: '123',
appId: '123',
messagingSenderId: '123',
projectId: '123',
));
firestore = FirebaseFirestore.instance;
firestoreSecondary = FirebaseFirestore.instanceFor(app: secondaryApp);
random = Random();
timer = Timer.periodic(
Duration(seconds: 1),
(t) {
var barNextInt = random.nextInt(999);
var bazNextInt = random.nextInt(999);
firestoreSecondary.collection('foo').doc('bar').set({'nextInt': barNextInt});
firestoreSecondary.collection('foo').doc('baz').set({'nextInt': bazNextInt});
},
);
firestoreSecondary.collection('foo').snapshots().listen(
(querySnapshot) {
compute(functionWithDocsArg, querySnapshot.docs);
},
);
});
test('extends $Query', () async {
var ref = firestore.collection('foo');
await Future.delayed(const Duration(seconds: 29), () {});
expect(ref.firestore, equals(firestore));
});
});
}
int functionWithDocsArg(List<DocumentSnapshot> docs) {
debugPrint("DateTime.now():");
debugPrint(DateTime.now().toString());
debugPrint('functionWithDocsArg computed!');
return 0;
}
Error:
MissingPluginException(No implementation found for method Query#addSnapshotListener on channel plugins.flutter.io/firebase_firestore)
package:flutter/src/services/platform_channel.dart 157:7 MethodChannel._invokeMethod
===== asynchronous gap ===========================
dart:async _asyncErrorWrapperHelper
package:cloud_firestore_platform_interface/src/method_channel/method_channel_query.dart MethodChannelQuery.snapshots.<fn>
I am not sure if it is reproducable. If you have an idea, just let me know.
You don't need to write a full mocked test for this. If the issue is reproducible with a basic test collection and an isolate in a fresh example project basic main.dart that is all we need.
But we do need a reproducible sample where we can also see the reported behavior in DevTools or a profiler.
Using plain Dart Isolates, I was able to avoid memory leak. But, I thought that creates a lot of overhead spawning an isolate and running the function every time firestore listener fired. So, I tried to initialize firebase and listen to firestore on an Isolate but it is not possible because plain Dart isolates do not support plugins. As a result, I tried to use IsolateHandler package which enables using plugins on isolates. But, I still have main UI thread freezing problem although firestore listener is completely running on a separate isolate. I guess it still tries to use main thread. I filed another issue for this.
I am no longer interested in this issue but it is still there which may cause headache later for some other people. If you want to work on it, I already provided the steps to reproduce it.
I was able to reproduce this on the latest master 1.24.0-8.0.pre.304 with
firebase_core: ^0.5.2 and cloud_firestore: ^0.14.3.
The list argument didn't seem to change anything.
flutter doctor -v
[✓] Flutter (Channel master, 1.24.0-8.0.pre.304, on macOS 11.0.1 20B29 darwin-x64, locale en-GB)
• Flutter version 1.24.0-8.0.pre.304 at /Users/markus/development/flutter_master
• Framework revision c6290500f8 (12 hours ago), 2020-11-18 17:29:28 -0800
• Engine revision 35a0b9fe68
• Dart version 2.12.0 (build 2.12.0-50.0.dev)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.1)
• Android SDK at /Users/markus/Library/Android/sdk
• Platform android-30, build-tools 30.0.1
• Java binary at: /Users/markus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/201.6953283/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 12.2)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 12.2, Build version 12B45b
• CocoaPods version 1.10.0
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 4.1)
• Android Studio at /Users/markus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/201.6953283/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 1.8.0_242-release-1644-b3-6915495)
[✓] Connected device (4 available)
• Nevercode’s iPhone (mobile) • b668e524315069f3db3661ac11ff1f66afafebdb • ios • iOS 14.2
• macOS (desktop) • macos • darwin-x64 • macOS 11.0.1 20B29 darwin-x64
• Web Server (web) • web-server • web-javascript • Flutter Tools
• Chrome (web) • chrome • web-javascript • Google Chrome 87.0.4280.67
• No issues found!
Minimal reproducible code sample
import 'dart:async';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Timer timer = null;
num i = 0;
@override
void initState() {
super.initState();
FirebaseFirestore.instance.collection('test').snapshots().listen((event) => compute(functionWithDocsArg, event.docs.length));
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text("DocumentReference example"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
RaisedButton(
child: Text(timer == null ? "Start updating document" : "Stop"),
onPressed: () {
if (timer == null) {
setState(() {
timer = Timer.periodic(Duration(milliseconds: 100), (t) {
i++;
FirebaseFirestore.instance.collection('test').doc('testA').set({"int": i}).catchError((e) => print(e));
FirebaseFirestore.instance.collection('test').doc('testB').set({"int": i}).catchError((e) => print(e));
});
});
} else {
setState(() {
timer.cancel();
timer = null;
i = 0;
});
}
},
),
CircularProgressIndicator(),
],
),
),
),
);
}
}
int functionWithDocsArg(int docs) {
debugPrint("DateTime.now():");
debugPrint(DateTime.now().toString());
debugPrint('functionWithDocsArg computed!');
return 0;
}
This does hang the UI thread and can crash pretty easily.
Logs
E/CursorWindow(13721): CursorWindow: mmap() failed: errno=12.
D/AndroidRuntime(13721): Shutting down VM
E/AndroidRuntime(13721): FATAL EXCEPTION: main
E/AndroidRuntime(13721): Process: com.nevercode.triage, PID: 13721
E/AndroidRuntime(13721): java.lang.RuntimeException: Internal error in Cloud Firestore (21.7.1).
E/AndroidRuntime(13721): at com.google.firebase.firestore.util.AsyncQueue.lambda$panic$3(AsyncQueue.java:534)
E/AndroidRuntime(13721): at com.google.firebase.firestore.util.AsyncQueue$$Lambda$3.run(Unknown Source:2)
E/AndroidRuntime(13721): at android.os.Handler.handleCallback(Handler.java:938)
E/AndroidRuntime(13721): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(13721): at android.os.Looper.loop(Looper.java:223)
E/AndroidRuntime(13721): at android.app.ActivityThread.main(ActivityThread.java:7656)
E/AndroidRuntime(13721): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(13721): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
E/AndroidRuntime(13721): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
E/AndroidRuntime(13721): Caused by: android.database.CursorWindowAllocationException: Could not allocate CursorWindow '/data/user/0/com.nevercode.triage/databases/firestore.%5BDEFAULT%5D.triage-79c7c.%28default%29' of size 2097152 due to error -12.
E/AndroidRuntime(13721): at android.database.CursorWindow.nativeCreate(Native Method)
E/AndroidRuntime(13721): at android.database.CursorWindow.<init>(CursorWindow.java:139)
E/AndroidRuntime(13721): at android.database.CursorWindow.<init>(CursorWindow.java:120)
E/AndroidRuntime(13721): at android.database.AbstractWindowedCursor.clearOrCreateWindow(AbstractWindowedCursor.java:202)
E/AndroidRuntime(13721): at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:147)
E/AndroidRuntime(13721): at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:140)
E/AndroidRuntime(13721): at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:231)
E/AndroidRuntime(13721): at android.database.AbstractCursor.moveToNext(AbstractCursor.java:280)
E/AndroidRuntime(13721): at com.google.firebase.firestore.local.SQLitePersistence$Query.forEach(SQLitePersistence.java:463)
E/AndroidRuntime(13721): at com.google.firebase.firestore.local.SQLiteRemoteDocumentCache.getAll(SQLiteRemoteDocumentCache.java:113)
E/AndroidRuntime(13721): at com.google.firebase.firestore.local.LocalStore.lambda$applyRemoteEvent$5(LocalStore.java:381)
E/AndroidRuntime(13721): at com.google.firebase.firestore.local.LocalStore$$Lambda$6.get(Unknown Source:6)
E/AndroidRuntime(13721): at com.google.firebase.firestore.local.SQLitePersistence.runTransaction(SQLitePersistence.java:207)
E/AndroidRuntime(13721): at com.google.firebase.firestore.local.LocalStore.applyRemoteEvent(LocalStore.java:337)
E/AndroidRuntime(13721): at com.google.firebase.firestore.core.SyncEngine.handleRemoteEvent(SyncEngine.java:342)
E/AndroidRuntime(13721): at com.google.firebase.firestore.core.MemoryComponentProvider$RemoteStoreCallback.handleRemoteEvent(MemoryComponentProvider.java:94)
E/AndroidRuntime(13721): at com.google.firebase.firestore.remote.RemoteStore.raiseWatchSnapshot(RemoteStore.java:552)
E/AndroidRuntime(13721): at com.google.firebase.firestore.remote.RemoteStore.handleWatchChange(RemoteStore.java:464)
E/AndroidRuntime(13721): at com.google.firebase.firestore.remote.RemoteStore.access$100(RemoteStore.java:53)
E/AndroidRuntime(13721): at com.google.firebase.firestore.remote.RemoteStore$1.onWatchChange(RemoteStore.java:176)
E/AndroidRuntime(13721): at com.google.firebase.firestore.remote.WatchStream.onNext(WatchStream.java:108)
E/AndroidRuntime(13721): at com.google.firebase.firestore.remote.WatchStream.onNext(WatchStream.java:38)
E/AndroidRuntime(13721): at com.google.firebase.firestore.remote.AbstractStream$StreamObserver.lambda$onNext$1(AbstractStream.java:119)
E/AndroidRuntime(13721): at com.google.firebase.firestore.remote.AbstractStream$StreamObserver$$Lambda$2.run(Unknown Source:4)
E/AndroidRuntime(13721): at com.google.firebase.firestore.remote.AbstractStream$CloseGuardedRunner.run(AbstractStream.java:67)
E/AndroidRuntime(13721): at com.google.firebase.firestore.remote.AbstractStream$StreamObserver.onNext(AbstractStream.java:110)
E/AndroidRuntime(13721): at com.google.firebase.firestore.remote.FirestoreChannel$1.onMessage(FirestoreChannel.java:125)
E/AndroidRuntime(13721): at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1MessagesAvailable.runInternal(ClientCallImpl.java:658)
E/AndroidRuntime(13721): at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1MessagesAvailable.runInContext(ClientCallImpl.java:643)
E/AndroidRuntime(13721): at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37)
E/AndroidRuntime(13721): at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:123)
E/AndroidRuntime(13721): at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
E/AndroidRuntime(13721): at java.util.concurrent.FutureTask.run(FutureTask.java:266)
E/AndroidRuntime(13721): at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
E/AndroidRuntime(13721): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
E/AndroidRuntime(13721): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
E/AndroidRuntime(13721): at com.google.firebase.firestore.util.AsyncQueue$SynchronizedShutdownAwareExecutor$DelayedStartFactory.run(AsyncQueue.java:229)
E/AndroidRuntime(13721): at java.lang.Thread.run(Thread.java:923)
E/DartVM (13721): Exhausted heap space, trying to allocate 248992 bytes.
E/Dart (13721): ../../third_party/dart/runtime/vm/object.cc: 2588: error: Out of memory.
E/DartVM (13721): version=2.12.0-50.0.dev (dev) (Mon Nov 16 16:23:04 2020 -0800) on "android_ia32"
E/DartVM (13721): pid=13721, thread=13959, isolate_group=_spawn(0xf01d5a90), isolate=_spawn(0xe9f99a70)
E/DartVM (13721): isolate_instructions=c05a4600, vm_instructions=c05a4600
E/DartVM (13721): pc 0xc06cf9be fp 0xaa0fb4e8 /data/app/~~kmt9Q9_XJc8qao_sCSt-TQ==/com.nevercode.triage-hpmNQvNMjCystuibbdfQgA==/lib/x86/libflutter.so+0x180a9be
E/DartVM (13721): pc 0xc0954e11 fp 0xaa0fb508 /data/app/~~kmt9Q9_XJc8qao_sCSt-TQ==/com.nevercode.triage-hpmNQvNMjCystuibbdfQgA==/lib/x86/libflutter.so+0x1a8fe11
E/DartVM (13721): pc 0xc05a4797 fp 0xaa0fb538 /data/app/~~kmt9Q9_XJc8qao_sCSt-TQ==/com.nevercode.triage-hpmNQvNMjCystuibbdfQgA==/lib/x86/libflutter.so+0x16df797
E/DartVM (13721): pc 0xc064c6a0 fp 0xaa0fb588 /data/app/~~kmt9Q9_XJc8qao_sCSt-TQ==/com.nevercode.triage-hpmNQvNMjCystuibbdfQgA==/lib/x86/libflutter.so+0x17876a0
E/DartVM (13721): pc 0xc06a4b9a fp 0xaa0fb5d8 /data/app/~~kmt9Q9_XJc8qao_sCSt-TQ==/com.nevercode.triage-hpmNQvNMjCystuibbdfQgA==/lib/x86/libflutter.so+0x17dfb9a
E/DartVM (13721): pc 0xc088dbc5 fp 0xaa0fb628 /data/app/~~kmt9Q9_XJc8qao_sCSt-TQ==/com.nevercode.triage-hpmNQvNMjCystuibbdfQgA==/lib/x86/libflutter.so+0x19c8bc5
E/DartVM (13721): pc 0xc063cd95 fp 0xaa0fb6b8 /data/app/~~kmt9Q9_XJc8qao_sCSt-TQ==/com.nevercode.triage-hpmNQvNMjCystuibbdfQgA==/lib/x86/libflutter.so+0x1777d95
E/DartVM (13721): pc 0xc063bcbf fp 0xaa0fb778 /data/app/~~kmt9Q9_XJc8qao_sCSt-TQ==/com.nevercode.triage-hpmNQvNMjCystuibbdfQgA==/lib/x86/libflutter.so+0x1776cbf
E/DartVM (13721): pc 0xc063b647 fp 0xaa0fb7d8 /data/app/~~kmt9Q9_XJc8qao_sCSt-TQ==/com.nevercode.triage-hpmNQvNMjCystuibbdfQgA==/lib/x86/libflutter.so+0x1776647
E/DartVM (13721): pc 0xc063bdeb fp 0xaa0fbac8 /data/app/~~kmt9Q9_XJc8qao_sCSt-TQ==/com.nevercode.triage-hpmNQvNMjCystuibbdfQgA==/lib/x86/libflutter.so+0x1776deb
E/DartVM (13721): pc 0xc0953c49 fp 0xaa0fbb78 /data/app/~~kmt9Q9_XJc8qao_sCSt-TQ==/com.nevercode.triage-hpmNQvNMjCystuibbdfQgA==/lib/x86/libflutter.so+0x1a8ec49
E/DartVM (13721): pc 0xc0137a67 fp 0xaa0fbba8 /data/app/~~kmt9Q9_XJc8qao_sCSt-TQ==/com.nevercode.triage-hpmNQvNMjCystuibbdfQgA==/lib/x86/libflutter.so+0x1272a67
E/DartVM (13721): pc 0xc0137b62 fp 0xaa0fbc18 /data/app/~~kmt9Q9_XJc8qao_sCSt-TQ==/com.nevercode.triage-hpmNQvNMjCystuibbdfQgA==/lib/x86/libflutter.so+0x1272b62
I/flutter (13721): DateTime.now():
E/DartVM (13721): pc 0xc0139f02 fp 0xaa0fbc68 /data/app/~~kmt9Q9_XJc8qao_sCSt-TQ==/com.nevercode.triage-hpmNQvNMjCystuibbdfQgA==/lib/x86/libflutter.so+0x1274f02
E/DartVM (13721): pc 0xc00faaa2 fp 0xaa0fbc98 /data/app/~~kmt9Q9_XJc8qao_sCSt-TQ==/com.nevercode.triage-hpmNQvNMjCystuibbdfQgA==/lib/x86/libflutter.so+0x1235aa2
E/DartVM (13721): pc 0xc00fa9ff fp 0xaa0fbcc8 /data/app/~~kmt9Q9_XJc8qao_sCSt-TQ==/com.nevercode.triage-hpmNQvNMjCystuibbdfQgA==/lib/x86/libflutter.so+0x12359ff
E/DartVM (13721): pc 0xc0138b9e fp 0xaa0fbd18 /data/app/~~kmt9Q9_XJc8qao_sCSt-TQ==/com.nevercode.triage-hpmNQvNMjCystuibbdfQgA==/lib/x86/libflutter.so+0x1273b9e
E/DartVM (13721): pc 0xc0136bb5 fp 0xaa0fbd88 /data/app/~~kmt9Q9_XJc8qao_sCSt-TQ==/com.nevercode.triage-hpmNQvNMjCystuibbdfQgA==/lib/x86/libflutter.so+0x1271bb5
E/DartVM (13721): pc 0xc013867e fp 0xaa0fbfa8 /data/app/~~kmt9Q9_XJc8qao_sCSt-TQ==/com.nevercode.triage-hpmNQvNMjCystuibbdfQgA==/lib/x86/libflutter.so+0x127367e
E/DartVM (13721): pc 0xc05bb16b fp 0xaa0fc028 /data/app/~~kmt9Q9_XJc8qao_sCSt-TQ==/com.nevercode.triage-hpmNQvNMjCystuibbdfQgA==/lib/x86/libflutter.so+0x16f616b
E/DartVM (13721): pc 0xc05bb0f5 fp 0xaa0fc058 /data/app/~~kmt9Q9_XJc8qao_sCSt-TQ==/com.nevercode.triage-hpmNQvNMjCystuibbdfQgA==/lib/x86/libflutter.so+0x16f60f5
E/DartVM (13721): pc 0xc074923c fp 0xaa0fc0e8 /data/app/~~kmt9Q9_XJc8qao_sCSt-TQ==/com.nevercode.triage-hpmNQvNMjCystuibbdfQgA==/lib/x86/libflutter.so+0x188423c
E/DartVM (13721): pc 0xc074954a fp 0xaa0fc118 /data/app/~~kmt9Q9_XJc8qao_sCSt-TQ==/com.nevercode.triage-hpmNQvNMjCystuibbdfQgA==/lib/x86/libflutter.so+0x188454a
E/DartVM (13721): pc 0xc06cb7e6 fp 0xaa0fc178 /data/app/~~kmt9Q9_XJc8qao_sCSt-TQ==/com.nevercode.triage-hpmNQvNMjCystuibbdfQgA==/lib/x86/libflutter.so+0x18067e6
E/DartVM (13721): pc 0xee4f4975 fp 0xaa0fc198 /apex/com.android.runtime/lib/bionic/libc.so+0xe6975
E/DartVM (13721): pc 0xee486568 fp 0xaa0fc1c8 /apex/com.android.runtime/lib/bionic/libc.so+0x78568
E/DartVM (13721): -- End of DumpStackTrace
F/libc (13721): Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 13959 (DartWorker), pid 13721 (evercode.triage)
Lost connection to device.
This is also reproducible with a regular callback.
Minimal reproducible code sample
import 'dart:async';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Timer timer;
num i = 0;
@override
void initState() {
super.initState();
FirebaseFirestore.instance.collection('test').snapshots().listen((event) => print(event.docs[0].get("int")));
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text("DocumentReference example"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
RaisedButton(
child: Text(timer == null ? "Start updating document" : "Stop"),
onPressed: () {
if (timer == null) {
setState(() {
timer = Timer.periodic(Duration(milliseconds: 100), (t) {
i++;
FirebaseFirestore.instance.collection('test').doc('testA').set({"int": i}).catchError((e) => print(e));
FirebaseFirestore.instance.collection('test').doc('testB').set({"int": i}).catchError((e) => print(e));
});
});
} else {
setState(() {
timer.cancel();
timer = null;
i = 0;
});
}
},
),
CircularProgressIndicator(),
],
),
),
),
);
}
}
Logs
W/libc (19208): pthread_create failed: couldn't allocate 1085440-bytes mapped space: Out of memory
W/evercode.triag(19208): Throwing OutOfMemoryError "pthread_create (1040KB stack) failed: Try again" (VmSize 4011424 kB)
E/AndroidRuntime(19208): FATAL EXCEPTION: main
E/AndroidRuntime(19208): Process: com.nevercode.triage, PID: 19208
E/AndroidRuntime(19208): java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Try again
E/AndroidRuntime(19208): at java.lang.Thread.nativeCreate(Native Method)
E/AndroidRuntime(19208): at java.lang.Thread.start(Thread.java:887)
E/AndroidRuntime(19208): at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:975)
E/AndroidRuntime(19208): at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1393)
E/AndroidRuntime(19208): at com.google.android.gms.tasks.Tasks.call(Unknown Source:14)
E/AndroidRuntime(19208): at io.flutter.plugins.firebase.firestore.FlutterFirebaseFirestorePlugin.documentSet(FlutterFirebaseFirestorePlugin.java:407)
E/AndroidRuntime(19208): at io.flutter.plugins.firebase.firestore.FlutterFirebaseFirestorePlugin.onMethodCall(FlutterFirebaseFirestorePlugin.java:537)
E/AndroidRuntime(19208): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:233)
E/AndroidRuntime(19208): at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:85)
E/AndroidRuntime(19208): at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:735)
E/AndroidRuntime(19208): at android.os.MessageQueue.nativePollOnce(Native Method)
E/AndroidRuntime(19208): at android.os.MessageQueue.next(MessageQueue.java:335)
E/AndroidRuntime(19208): at android.os.Looper.loop(Looper.java:183)
E/AndroidRuntime(19208): at android.app.ActivityThread.main(ActivityThread.java:7656)
E/AndroidRuntime(19208): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(19208): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
E/AndroidRuntime(19208): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
I/Process (19208): Sending signal. PID: 19208 SIG: 9
Lost connection to device.
Most helpful comment
This is also reproducible with a regular callback.
Minimal reproducible code sample
Logs