diff --git a/README.md b/README.md
index bcc3bce38..c937d3a4e 100644
--- a/README.md
+++ b/README.md
@@ -24,7 +24,6 @@ Aves is a gallery and metadata explorer app. It is built for Android, with Flutt
## Known Issues
-- privacy: cannot opt out of Crashlytics reporting (cf [flutterfire issue #1143](https://github.com/FirebaseExtended/flutterfire/issues/1143))
- gesture: double tap on image does not zoom on tapped area (cf [photo_view issue #82](https://github.com/renancaraujo/photo_view/issues/82))
- performance: image info page stutters the first time it loads a Google Maps view (cf [flutter issue #28493](https://github.com/flutter/flutter/issues/28493))
- performance: image decoding is slow
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 7016ee892..ac8bdd2e6 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -106,6 +106,9 @@
android:value="${googleApiKey}" />
+
diff --git a/android/build.gradle b/android/build.gradle
index cb1faadbe..ca6b56711 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -7,7 +7,7 @@ buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:3.6.3'
classpath 'com.google.gms:google-services:4.3.3'
- classpath 'com.google.firebase:firebase-crashlytics-gradle:2.1.1'
+ classpath 'com.google.firebase:firebase-crashlytics-gradle:2.2.0'
}
}
diff --git a/lib/main.dart b/lib/main.dart
index ed627f0e8..5298919b4 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,8 +1,11 @@
+import 'dart:isolate';
+
import 'package:aves/model/settings/settings.dart';
import 'package:aves/widgets/common/data_providers/settings_provider.dart';
import 'package:aves/widgets/common/icons.dart';
import 'package:aves/widgets/home_page.dart';
import 'package:aves/widgets/welcome_page.dart';
+import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@@ -11,9 +14,15 @@ import 'package:overlay_support/overlay_support.dart';
void main() {
// HttpClient.enableTimelineLogging = true; // enable network traffic logging
// debugPrintGestureArenaDiagnostics = true;
- Crashlytics.instance.enableInDevMode = true;
- FlutterError.onError = Crashlytics.instance.recordFlutterError;
+ Isolate.current.addErrorListener(RawReceivePort((pair) async {
+ final List errorAndStacktrace = pair;
+ await FirebaseCrashlytics.instance.recordError(
+ errorAndStacktrace.first,
+ errorAndStacktrace.last,
+ );
+ }).sendPort);
+
runApp(AvesApp());
}
@@ -34,7 +43,12 @@ class _AvesAppState extends State {
@override
void initState() {
super.initState();
- _appSetup = settings.init();
+ _appSetup = _setup();
+ }
+
+ Future _setup() async {
+ await Firebase.initializeApp().then((app) => FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError);
+ await settings.init();
}
@override
@@ -67,7 +81,14 @@ class _AvesAppState extends State {
home: FutureBuilder(
future: _appSetup,
builder: (context, snapshot) {
- if (snapshot.hasError) return Icon(AIcons.error);
+ if (snapshot.hasError) {
+ return Column(
+ children: [
+ Icon(AIcons.error),
+ Text(snapshot.error),
+ ],
+ );
+ }
if (snapshot.connectionState != ConnectionState.done) return Scaffold();
return settings.hasAcceptedTerms ? HomePage() : WelcomePage();
},
diff --git a/lib/model/settings/settings.dart b/lib/model/settings/settings.dart
index 7460a89bf..448e5c103 100644
--- a/lib/model/settings/settings.dart
+++ b/lib/model/settings/settings.dart
@@ -1,8 +1,11 @@
import 'package:aves/model/settings/coordinate_format.dart';
import 'package:aves/model/settings/home_page.dart';
import 'package:aves/widgets/fullscreen/info/location_section.dart';
+import 'package:firebase_core/firebase_core.dart';
+import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
+import 'package:pedantic/pedantic.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../source/enums.dart';
@@ -18,6 +21,7 @@ class Settings extends ChangeNotifier {
// app
static const hasAcceptedTermsKey = 'has_accepted_terms';
+ static const isCrashlyticsEnabledKey = 'is_crashlytics_enabled';
static const mustBackTwiceToExitKey = 'must_back_twice_to_exit';
static const homePageKey = 'home_page';
static const catalogTimeZoneKey = 'catalog_time_zone';
@@ -42,6 +46,12 @@ class Settings extends ChangeNotifier {
Future init() async {
_prefs = await SharedPreferences.getInstance();
+ await _setupCrashlytics();
+ }
+
+ Future _setupCrashlytics() async {
+ await Firebase.app().setAutomaticDataCollectionEnabled(isCrashlyticsEnabled);
+ await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(isCrashlyticsEnabled);
}
Future reset() {
@@ -54,6 +64,13 @@ class Settings extends ChangeNotifier {
set hasAcceptedTerms(bool newValue) => setAndNotify(hasAcceptedTermsKey, newValue);
+ bool get isCrashlyticsEnabled => getBoolOrDefault(isCrashlyticsEnabledKey, false);
+
+ set isCrashlyticsEnabled(bool newValue) {
+ setAndNotify(isCrashlyticsEnabledKey, newValue);
+ unawaited(_setupCrashlytics());
+ }
+
bool get mustBackTwiceToExit => getBoolOrDefault(mustBackTwiceToExitKey, true);
set mustBackTwiceToExit(bool newValue) => setAndNotify(mustBackTwiceToExitKey, newValue);
diff --git a/lib/widgets/debug_page.dart b/lib/widgets/debug_page.dart
index 575fa727a..e5fb45a72 100644
--- a/lib/widgets/debug_page.dart
+++ b/lib/widgets/debug_page.dart
@@ -12,6 +12,8 @@ import 'package:aves/utils/android_file_utils.dart';
import 'package:aves/utils/file_utils.dart';
import 'package:aves/widgets/common/data_providers/media_query_data_provider.dart';
import 'package:aves/widgets/fullscreen/info/info_page.dart';
+import 'package:firebase_core/firebase_core.dart';
+import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_svg/flutter_svg.dart';
@@ -95,6 +97,21 @@ class DebugPageState extends State {
label: '$timeDilation',
),
Divider(),
+ Row(
+ children: [
+ Expanded(
+ child: Text('Crashlytics'),
+ ),
+ SizedBox(width: 8),
+ RaisedButton(
+ onPressed: FirebaseCrashlytics.instance.crash,
+ child: Text('Crash'),
+ ),
+ ],
+ ),
+ Text('Firebase data collection: ${Firebase.app().isAutomaticDataCollectionEnabled ? 'enabled' : 'disabled'}'),
+ Text('Crashlytics collection: ${FirebaseCrashlytics.instance.isCrashlyticsCollectionEnabled ? 'enabled' : 'disabled'}'),
+ Divider(),
Text('Entries: ${entries.length}'),
Text('Catalogued: ${catalogued.length}'),
Text('With GPS: ${withGps.length}'),
diff --git a/lib/widgets/settings/settings_page.dart b/lib/widgets/settings/settings_page.dart
index d58633709..c57913b10 100644
--- a/lib/widgets/settings/settings_page.dart
+++ b/lib/widgets/settings/settings_page.dart
@@ -70,6 +70,12 @@ class SettingsPage extends StatelessWidget {
}
},
),
+ SectionTitle('Privacy'),
+ SwitchListTile(
+ value: settings.isCrashlyticsEnabled,
+ onChanged: (v) => settings.isCrashlyticsEnabled = v,
+ title: Text('Allow anonymous crash reporting'),
+ ),
],
),
),
diff --git a/pubspec.lock b/pubspec.lock
index 46fc5ada4..dc4027043 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -180,13 +180,48 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.0-nullsafety.1"
+ firebase:
+ dependency: transitive
+ description:
+ name: firebase
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "7.3.0"
+ firebase_core:
+ dependency: "direct main"
+ description:
+ name: firebase_core
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.5.0"
+ firebase_core_platform_interface:
+ dependency: transitive
+ description:
+ name: firebase_core_platform_interface
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.0.0"
+ firebase_core_web:
+ dependency: transitive
+ description:
+ name: firebase_core_web
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.2.0"
firebase_crashlytics:
dependency: "direct main"
description:
name: firebase_crashlytics
url: "https://pub.dartlang.org"
source: hosted
- version: "0.1.4+1"
+ version: "0.2.0-dev.5"
+ firebase_crashlytics_platform_interface:
+ dependency: transitive
+ description:
+ name: firebase_crashlytics_platform_interface
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.0.0-dev.2"
flushbar:
dependency: "direct main"
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 9fbb97e27..5a59a228d 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -47,7 +47,8 @@ dependencies:
# path: ../expansion_tile_card
git:
url: git://github.com/deckerst/expansion_tile_card.git
- firebase_crashlytics:
+ firebase_core: "^0.5.0"
+ firebase_crashlytics: "^0.2.0-dev.5"
flushbar:
flutter_ijkplayer:
# path: ../flutter_ijkplayer