mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-01-22 08:46:18 +01:00
Add Firebase Crashlytics
This commit is contained in:
parent
e1bfca432e
commit
5473ff5599
12 changed files with 178 additions and 0 deletions
|
@ -128,3 +128,6 @@ dependencies {
|
|||
implementation 'com.nkming.nc_photos.np_android_core:np_android_core'
|
||||
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:2.0.3"
|
||||
}
|
||||
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
apply plugin: 'com.google.firebase.crashlytics'
|
||||
|
|
|
@ -62,5 +62,8 @@
|
|||
<meta-data
|
||||
android:name="com.google.android.gms.ads.APPLICATION_ID"
|
||||
android:value="" />
|
||||
<meta-data
|
||||
android:name="firebase_crashlytics_collection_enabled"
|
||||
android:value="false" />
|
||||
</application>
|
||||
</manifest>
|
||||
|
|
|
@ -8,6 +8,8 @@ buildscript {
|
|||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.4.2'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath 'com.google.gms:google-services:4.3.14'
|
||||
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:event_bus/event_bus.dart';
|
||||
import 'package:firebase_core/firebase_core.dart';
|
||||
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:google_mobile_ads/google_mobile_ads.dart';
|
||||
import 'package:kiwi/kiwi.dart';
|
||||
|
@ -42,6 +46,7 @@ import 'package:nc_photos/entity/tagged_file/data_source.dart';
|
|||
import 'package:nc_photos/k.dart' as k;
|
||||
import 'package:nc_photos/mobile/android/android_info.dart';
|
||||
import 'package:nc_photos/mobile/self_signed_cert_manager.dart';
|
||||
import 'package:nc_photos/object_extension.dart';
|
||||
import 'package:nc_photos/platform/features.dart' as features;
|
||||
import 'package:nc_photos/session_storage.dart';
|
||||
import 'package:nc_photos/touch_manager.dart';
|
||||
|
@ -85,6 +90,7 @@ Future<void> init(InitIsolateType isolateType) async {
|
|||
// init session storage
|
||||
SessionStorage();
|
||||
|
||||
await _initFirebase();
|
||||
await _initAds();
|
||||
|
||||
_hasInitedInThisIsolate = true;
|
||||
|
@ -98,6 +104,16 @@ void initLog() {
|
|||
np_log.initLog(
|
||||
isDebugMode: np_log.isDevMode,
|
||||
print: (log) => debugPrint(log, wrapWidth: 1024),
|
||||
onLog: (record) {
|
||||
if (_shouldReportCrashlytics(record)) {
|
||||
FirebaseCrashlytics.instance.recordError(
|
||||
record.error,
|
||||
record.stackTrace,
|
||||
reason: record.message,
|
||||
printDetails: false,
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -236,5 +252,39 @@ Future<InitializationStatus> _initAds() {
|
|||
return MobileAds.instance.initialize();
|
||||
}
|
||||
|
||||
Future<void> _initFirebase() async {
|
||||
await Firebase.initializeApp();
|
||||
|
||||
// Crashlytics
|
||||
if (features.isSupportCrashlytics) {
|
||||
if (kDebugMode) {
|
||||
await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(false);
|
||||
await FirebaseCrashlytics.instance.deleteUnsentReports();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool _shouldReportCrashlytics(LogRecord record) {
|
||||
if (kDebugMode ||
|
||||
!features.isSupportCrashlytics ||
|
||||
record.level < Level.SHOUT) {
|
||||
return false;
|
||||
}
|
||||
final e = record.error;
|
||||
// We ignore these SocketExceptions as they are likely caused by an unstable
|
||||
// internet connection
|
||||
// 7: No address associated with hostname
|
||||
// 101: Network is unreachable
|
||||
// 103: Software caused connection abort
|
||||
// 104: Connection reset by peer
|
||||
// 110: Connection timed out
|
||||
// 113: No route to host
|
||||
if (e is SocketException &&
|
||||
e.osError?.errorCode.isIn([7, 101, 103, 104, 110, 113]) == true) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
final _log = Logger("app_init");
|
||||
var _hasInitedInThisIsolate = false;
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
"settingsPrivacyTitle": "Privacy",
|
||||
"settingsPrivacyDescription": "Privacy-related settings",
|
||||
"settingsPrivacyPageTitle": "Privacy settings",
|
||||
"settingsAnalyticsTitle": "Analytics",
|
||||
"settingsAnalyticsSubtitle": "Collect analytics after an error to help developers better diagnose the issue",
|
||||
"settingsPrivacyPolicyTitle": "Privacy policy",
|
||||
"setupPrivacyAgreeStatement": "Please read carefully the above privacy policy. By continuing, you agree to our privacy policy",
|
||||
"photosTabLabel": "Photos",
|
||||
|
|
|
@ -3,4 +3,7 @@ import 'package:np_common/object_util.dart';
|
|||
extension ObjectExtension<T> on T {
|
||||
/// Deprecated, use [let]
|
||||
U run<U>(U Function(T obj) fn) => let(fn);
|
||||
|
||||
/// Return if this is contained inside [iterable]
|
||||
bool isIn(Iterable<T> iterable) => iterable.contains(this);
|
||||
}
|
||||
|
|
|
@ -6,3 +6,4 @@ final isSupportSelfSignedCert = getRawPlatform() == NpPlatform.android;
|
|||
final isSupportEnhancement = getRawPlatform() == NpPlatform.android;
|
||||
|
||||
final isSupportAds = getRawPlatform() != NpPlatform.web;
|
||||
final isSupportCrashlytics = getRawPlatform() != NpPlatform.web;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
|
@ -272,6 +273,15 @@ class _PrivacySettings extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _PrivacySettingsState extends State<_PrivacySettings> {
|
||||
@override
|
||||
initState() {
|
||||
super.initState();
|
||||
if (features.isSupportCrashlytics) {
|
||||
_isEnableAnalytics =
|
||||
FirebaseCrashlytics.instance.isCrashlyticsCollectionEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
build(BuildContext context) {
|
||||
return Scaffold(
|
||||
|
@ -291,6 +301,13 @@ class _PrivacySettingsState extends State<_PrivacySettings> {
|
|||
SliverList(
|
||||
delegate: SliverChildListDelegate(
|
||||
[
|
||||
if (features.isSupportCrashlytics)
|
||||
SwitchListTile(
|
||||
title: Text(L10n.global().settingsAnalyticsTitle),
|
||||
subtitle: Text(L10n.global().settingsAnalyticsSubtitle),
|
||||
value: _isEnableAnalytics,
|
||||
onChanged: (value) => _onAnalyticsChanged(value),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10n.global().settingsPrivacyPolicyTitle),
|
||||
onTap: () {
|
||||
|
@ -303,4 +320,13 @@ class _PrivacySettingsState extends State<_PrivacySettings> {
|
|||
],
|
||||
);
|
||||
}
|
||||
|
||||
void _onAnalyticsChanged(bool value) {
|
||||
setState(() {
|
||||
_isEnableAnalytics = value;
|
||||
});
|
||||
FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(value);
|
||||
}
|
||||
|
||||
late bool _isEnableAnalytics;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:nc_photos/app_localizations.dart';
|
||||
import 'package:nc_photos/controller/pref_controller.dart';
|
||||
import 'package:nc_photos/entity/pref.dart';
|
||||
import 'package:nc_photos/k.dart' as k;
|
||||
import 'package:nc_photos/platform/features.dart' as features;
|
||||
import 'package:nc_photos/url_launcher_util.dart';
|
||||
import 'package:nc_photos/widget/home.dart';
|
||||
import 'package:nc_photos/widget/sign_in.dart';
|
||||
|
@ -250,6 +253,17 @@ class _PrivacyState extends State<_Privacy> {
|
|||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SwitchListTile(
|
||||
title: Text(L10n.global().settingsAnalyticsTitle),
|
||||
value: _isEnableAnalytics,
|
||||
onChanged: _onAnalyticsValueChanged,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Text(L10n.global().settingsAnalyticsSubtitle),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: InkWell(
|
||||
|
@ -286,4 +300,25 @@ class _PrivacyState extends State<_Privacy> {
|
|||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
dispose() {
|
||||
super.dispose();
|
||||
// persist user's choice
|
||||
_log.info("[dispose] Analytics: $_isEnableAnalytics");
|
||||
if (features.isSupportCrashlytics) {
|
||||
FirebaseCrashlytics.instance
|
||||
.setCrashlyticsCollectionEnabled(_isEnableAnalytics);
|
||||
}
|
||||
}
|
||||
|
||||
void _onAnalyticsValueChanged(bool value) {
|
||||
setState(() {
|
||||
_isEnableAnalytics = value;
|
||||
});
|
||||
}
|
||||
|
||||
bool _isEnableAnalytics = true;
|
||||
|
||||
static final _log = Logger("widget.setup._PrivacyState");
|
||||
}
|
||||
|
|
|
@ -9,6 +9,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "67.0.0"
|
||||
_flutterfire_internals:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: _flutterfire_internals
|
||||
sha256: "4eec93681221723a686ad580c2e7d960e1017cf1a4e0a263c2573c2c6b0bf5cd"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.25"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -438,6 +446,46 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.0"
|
||||
firebase_core:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_core
|
||||
sha256: "53316975310c8af75a96e365f9fccb67d1c544ef0acdbf0d88bbe30eedd1c4f9"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.27.0"
|
||||
firebase_core_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_core_platform_interface
|
||||
sha256: c437ae5d17e6b5cc7981cf6fd458a5db4d12979905f9aafd1fea930428a9fe63
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.0"
|
||||
firebase_core_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_core_web
|
||||
sha256: c8e1d59385eee98de63c92f961d2a7062c5d9a65e7f45bdc7f1b0b205aab2492
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.11.5"
|
||||
firebase_crashlytics:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_crashlytics
|
||||
sha256: c4f1b723d417bc9c4774810e774ff91df8fb0032d33fb2888b2c887e865581b8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.4.18"
|
||||
firebase_crashlytics_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_crashlytics_platform_interface
|
||||
sha256: c5a11fca3df76a98e3fa68fde8b10a08aacb9a7639f619fbfd4dad6c67a08643
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.6.25"
|
||||
fixnum:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -163,6 +163,8 @@ dependencies:
|
|||
woozy_search: ^2.0.3
|
||||
# android/ios only
|
||||
google_mobile_ads: 5.1.0
|
||||
firebase_core:
|
||||
firebase_crashlytics: 3.4.18
|
||||
|
||||
dependency_overrides:
|
||||
video_player:
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:logging/logging.dart';
|
|||
void initLog({
|
||||
required bool isDebugMode,
|
||||
void Function(String) print = print,
|
||||
void Function(LogRecord record)? onLog,
|
||||
}) {
|
||||
Logger.root.level = !isDebugMode ? Level.WARNING : Level.ALL;
|
||||
Logger.root.onRecord.listen((record) {
|
||||
|
@ -35,6 +36,8 @@ void initLog({
|
|||
}
|
||||
print(msg);
|
||||
LogStream().add(msg);
|
||||
|
||||
onLog?.call(record);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue