diff --git a/.gitattributes b/.gitattributes index abc8d1511..92e6d9dae 100644 --- a/.gitattributes +++ b/.gitattributes @@ -38,5 +38,8 @@ GoogleService-Info.plist filter=git-crypt diff=git-crypt binary google-service.json filter=git-crypt diff=git-crypt binary +google-services.json filter=git-crypt diff=git-crypt binary +firebase_app_id_file.json filter=git-crypt diff=git-crypt binary +/lib/firebase_options.dart filter=git-crypt diff=git-crypt binary +/lib/config/config.dart filter=git-crypt diff=git-crypt binary /lib/firebase_options.dart filter=git-crypt diff=git-crypt binary -/lib/config/config.dart filter=git-crypt diff=git-crypt binary \ No newline at end of file diff --git a/.gitignore b/.gitignore index 5c72323be..2a457d671 100644 --- a/.gitignore +++ b/.gitignore @@ -43,9 +43,9 @@ app.*.map.json # Exceptions to above rules. /packages/flutter_tools/test/data/dart_dependencies_test/**/.packages /ios/build/ -/ios/Runner/GoogleService-Info.plist -/ios/firebase_app_id_file.json -/android/app/google-services.json +#/ios/Runner/GoogleService-Info.plist +#/ios/firebase_app_id_file.json +#/android/app/google-services.json /android/app/asd.json #*.g.dart @@ -57,9 +57,9 @@ app.*.map.json /assets/openl.json /assets/sentry.json -GoogleService-Info.plist -google-service.json -/lib/firebase_options.dart +#GoogleService-Info.plist +#google-service.json +#/lib/firebase_options.dart android/app/keystore.jks #/pubspec.lock diff --git a/README.md b/README.md index 0c3e8ecaf..aaa8b1e89 100644 --- a/README.md +++ b/README.md @@ -91,4 +91,5 @@ Translation ## About compiling flutter version is the latest release version \ -rename `/lib/config/config.dart.sample` to `/lib/config/config.dart` +rename `lib/config/config.dart.sample` to `lib/config/config.dart` \ +rename `lib/firebase_options_sample.dart` to `lib/firebase_options.dart` diff --git a/README_cn.md b/README_cn.md index 68f606335..5aa89fdbd 100644 --- a/README_cn.md +++ b/README_cn.md @@ -96,6 +96,6 @@ ehentai译文数据库 ## 编译相关 -flutter版本为最新release版本 \ -`/lib/config/config.dart` 文件为存放敏感信息数据的文件,github里看到是加密处理的 \ -如果需要自行编译的话,复制 `/lib/config.dart.sample` 为 `/lib/config/config.dart` 进行操作 +如果需要自行编译的话 \ +复制 `lib/config.dart.sample` 为 `lib/config/config.dart` \ +复制 `lib/firebase_options_sample.dart` 为 `lib/firebase_options.dart` diff --git a/android/app/build.gradle b/android/app/build.gradle index 6804e0ddb..0bd95f760 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -35,6 +35,10 @@ def _storeFile = file(System.getenv("KEYSTORE") ?: keystoreProperties.getPropert def _storePassword = System.getenv("KEYSTORE_PASSWORD") ?: keystoreProperties.getProperty("storePassword") apply plugin: 'com.android.application' +// START: FlutterFire Configuration +apply plugin: 'com.google.gms.google-services' +apply plugin: 'com.google.firebase.crashlytics' +// END: FlutterFire Configuration apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" diff --git a/android/app/google-services.json b/android/app/google-services.json new file mode 100644 index 000000000..bd7ad880c Binary files /dev/null and b/android/app/google-services.json differ diff --git a/android/build.gradle b/android/build.gradle index 3f423ed91..c474ae182 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -10,6 +10,10 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:7.4.2' + // START: FlutterFire Configuration + classpath 'com.google.gms:google-services:4.3.14' + classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1' + // END: FlutterFire Configuration classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index c9deedd31..0d754dfa1 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -15,6 +15,7 @@ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; BA373B2925D2A11600C042FA /* SecurityBlurEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA373B2825D2A11600C042FA /* SecurityBlurEffect.swift */; }; + BFED4257903270F2E29ACBB6 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 76AED4914C4C6C44220F53A2 /* GoogleService-Info.plist */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -49,6 +50,7 @@ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 76AED4914C4C6C44220F53A2 /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; @@ -116,6 +118,7 @@ BD2B51B0799E31FC8C88C126 /* Pods */, 8E17D831CCF214C421795E99 /* Frameworks */, BA3ACC1B286B687300C23A87 /* fehviewer.app */, + 76AED4914C4C6C44220F53A2 /* GoogleService-Info.plist */, ); sourceTree = ""; wrapsLines = 0; @@ -173,6 +176,7 @@ 3B06AD1E1E4923F5004D2608 /* Thin Binary */, BA0498CA2553F1EA008DE488 /* Embed App Extensions */, 95CD7AC50C01DD7235DDE61E /* [CP] Embed Pods Frameworks */, + F7742035D917A11792ED261A /* [firebase_crashlytics] Crashlytics Upload Symbols */, ); buildRules = ( ); @@ -230,6 +234,7 @@ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + BFED4257903270F2E29ACBB6 /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -306,6 +311,29 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; + F7742035D917A11792ED261A /* [firebase_crashlytics] Crashlytics Upload Symbols */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "\"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}\"", + "\"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/\"", + "\"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Info.plist\"", + "\"$(TARGET_BUILD_DIR)/$(EXECUTABLE_PATH)\"", + "\"$(PROJECT_DIR)/firebase_app_id_file.json\"", + ); + name = "[firebase_crashlytics] Crashlytics Upload Symbols"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"$PODS_ROOT/FirebaseCrashlytics/upload-symbols\" --flutter-project \"$PROJECT_DIR/firebase_app_id_file.json\" "; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -439,7 +467,7 @@ "$(PROJECT_DIR)/Flutter", ); MARKETING_VERSION = "$(FLUTTER_BUILD_NAME)"; - PRODUCT_BUNDLE_IDENTIFIER = dev2.cn.honjow.fehv; + PRODUCT_BUNDLE_IDENTIFIER = cn.honjow.fehv; PRODUCT_NAME = fehviewer; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -588,7 +616,7 @@ "$(PROJECT_DIR)/Flutter", ); MARKETING_VERSION = "$(FLUTTER_BUILD_NAME)"; - PRODUCT_BUNDLE_IDENTIFIER = dev2.cn.honjow.fehv; + PRODUCT_BUNDLE_IDENTIFIER = cn.honjow.fehv; PRODUCT_NAME = fehviewer; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -627,7 +655,7 @@ "$(PROJECT_DIR)/Flutter", ); MARKETING_VERSION = "$(FLUTTER_BUILD_NAME)"; - PRODUCT_BUNDLE_IDENTIFIER = dev2.cn.honjow.fehv; + PRODUCT_BUNDLE_IDENTIFIER = cn.honjow.fehv; PRODUCT_NAME = fehviewer; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; diff --git a/ios/Runner/GoogleService-Info.plist b/ios/Runner/GoogleService-Info.plist new file mode 100644 index 000000000..3aad85751 Binary files /dev/null and b/ios/Runner/GoogleService-Info.plist differ diff --git a/ios/firebase_app_id_file.json b/ios/firebase_app_id_file.json new file mode 100644 index 000000000..df49114e7 Binary files /dev/null and b/ios/firebase_app_id_file.json differ diff --git a/lib/common/global.dart b/lib/common/global.dart index 7e8382089..5db76719a 100644 --- a/lib/common/global.dart +++ b/lib/common/global.dart @@ -16,6 +16,8 @@ import 'package:fehviewer/store/hive/hive.dart'; import 'package:fehviewer/store/hive/hive_cache.dart'; import 'package:fehviewer/utils/http_override.dart'; import 'package:fehviewer/utils/storage.dart'; +import 'package:firebase_analytics/firebase_analytics.dart'; +import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:flutter_downloader/flutter_downloader.dart'; @@ -107,10 +109,15 @@ class Global { static bool canCheckBiometrics = false; + static bool enableFirebase = false; + User get user => profile.user; set user(User val) => profile = profile.copyWith(user: val); + static FirebaseApp? firebaseApp; + static FirebaseAnalytics? analytics; + // init static Future init() async { // 判断是否debug模式 diff --git a/lib/firebase_options.dart b/lib/firebase_options.dart new file mode 100644 index 000000000..46a89e7d7 Binary files /dev/null and b/lib/firebase_options.dart differ diff --git a/lib/firebase_options_sample.dart b/lib/firebase_options_sample.dart new file mode 100644 index 000000000..36e84e375 --- /dev/null +++ b/lib/firebase_options_sample.dart @@ -0,0 +1,10 @@ +import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; + +class DefaultFirebaseOptions { + static FirebaseOptions get currentPlatform => const FirebaseOptions( + apiKey: '', + appId: '', + messagingSenderId: '', + projectId: '', + ); +} diff --git a/lib/main.dart b/lib/main.dart index 8584dadf3..7b7b509e9 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -10,6 +10,9 @@ import 'package:fehviewer/common/service/theme_service.dart'; import 'package:fehviewer/fehviewer.dart'; import 'package:fehviewer/store/get_store.dart'; import 'package:fehviewer/widget/system_ui_overlay.dart'; +import 'package:firebase_analytics/firebase_analytics.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; @@ -19,6 +22,7 @@ import 'package:logger/logger.dart'; import 'package:oktoast/oktoast.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; +import 'firebase_options_sample.dart' as fo; import 'get_init.dart'; import 'widget/desktop.dart'; @@ -28,6 +32,17 @@ Future main() async { WidgetsFlutterBinding.ensureInitialized(); final dsn = await getSentryDsn(); + Global.enableFirebase = + fo.DefaultFirebaseOptions.currentPlatform.apiKey.isNotEmpty; + + if (Global.enableFirebase) { + final FirebaseApp firebaseApp = await Firebase.initializeApp( + options: fo.DefaultFirebaseOptions.currentPlatform, + ); + Global.firebaseApp = firebaseApp; + Global.analytics = FirebaseAnalytics.instanceFor(app: firebaseApp); + } + Get.lazyPut(() => LogService(), fenix: true); Get.lazyPut(() => GStore()); await Global.init(); @@ -43,6 +58,14 @@ Future main() async { resetLogLevel(); updateTagTranslate(); + if (Global.enableFirebase) { + FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError; + PlatformDispatcher.instance.onError = (error, stack) { + FirebaseCrashlytics.instance.recordError(error, stack, fatal: true); + return true; + }; + } + if (dsn != null && dsn.isNotEmpty) { await SentryFlutter.init( (SentryFlutterOptions options) { @@ -149,8 +172,8 @@ class _MyAppState extends State with WidgetsBindingObserver { debugShowCheckedModeBanner: false, onGenerateTitle: (BuildContext context) => L10n.of(context).app_title, navigatorObservers: [ - // if (GetPlatform.isMobile) - // FirebaseAnalyticsObserver(analytics: analytics), + if (GetPlatform.isMobile && Global.analytics != null) + FirebaseAnalyticsObserver(analytics: Global.analytics!), SentryNavigatorObserver(), FlutterSmartDialog.observer, MainNavigatorObserver(), diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index bc38db8b2..e95427652 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -7,6 +7,9 @@ import Foundation import bitsdojo_window_macos import device_info_plus +import firebase_analytics +import firebase_core +import firebase_crashlytics import isar_flutter_libs import package_info import package_info_plus @@ -22,6 +25,9 @@ import window_size func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { BitsdojoWindowPlugin.register(with: registry.registrar(forPlugin: "BitsdojoWindowPlugin")) DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) + FLTFirebaseAnalyticsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAnalyticsPlugin")) + FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) + FLTFirebaseCrashlyticsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCrashlyticsPlugin")) IsarFlutterLibsPlugin.register(with: registry.registrar(forPlugin: "IsarFlutterLibsPlugin")) FLTPackageInfoPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlugin")) FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) diff --git a/pubspec.lock b/pubspec.lock index 31aef575f..0697a0973 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -9,6 +9,14 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "61.0.0" + _flutterfire_internals: + dependency: transitive + description: + name: _flutterfire_internals + sha256: "5dadadeecceac19d6a63c9d2e037bb8df58ddd4aedb94e8a056af2f39ee50f9d" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.3.11" analyzer: dependency: transitive description: @@ -610,6 +618,70 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "6.0.0" + firebase_analytics: + dependency: "direct main" + description: + name: firebase_analytics + sha256: fb8c29d97d29aed258d2fd98ba0ffc04ccca2c7b830b149187679524757f5d9d + url: "https://pub.flutter-io.cn" + source: hosted + version: "10.6.3" + firebase_analytics_platform_interface: + dependency: transitive + description: + name: firebase_analytics_platform_interface + sha256: "85fe94377732a168896a705410441b721a49c0703679c24e3edca0c680a45bb7" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.7.5" + firebase_analytics_web: + dependency: transitive + description: + name: firebase_analytics_web + sha256: "99a39a97e4760011ca0f2135c68a40f65dc9b260a0c27db2fdcb1258052c588b" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.5.5+5" + firebase_core: + dependency: transitive + description: + name: firebase_core + sha256: "7706f4ade6cc2698c70074083bc262586a185047f6bfdd53938dcc35d35cbb9e" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.21.0" + firebase_core_platform_interface: + dependency: transitive + description: + name: firebase_core_platform_interface + sha256: c437ae5d17e6b5cc7981cf6fd458a5db4d12979905f9aafd1fea930428a9fe63 + url: "https://pub.flutter-io.cn" + source: hosted + version: "5.0.0" + firebase_core_web: + dependency: transitive + description: + name: firebase_core_web + sha256: "0631a2ec971dbc540275e2fa00c3a8a2676f0a7adbc3c197d6fba569db689d97" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.8.1" + firebase_crashlytics: + dependency: "direct main" + description: + name: firebase_crashlytics + sha256: c1f6b7a75df5f83af187b396d763de0e7673fcb358093e04be68e82e6d80d41a + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.4.3" + firebase_crashlytics_platform_interface: + dependency: transitive + description: + name: firebase_crashlytics_platform_interface + sha256: "08f0a3a99a12a31a47a08ccb268efe163c2f0d89fec74eb5b8a86b219611175c" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.6.11" fixnum: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index cb076261c..b82fd8bba 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -186,6 +186,8 @@ dependencies: flutter_widget_from_html_core: ^0.14.4 quiver: ^3.1.0 # 工具库 native_dio_adapter: ^1.0.0+2 + firebase_analytics: ^10.6.3 + firebase_crashlytics: ^3.4.3 dev_dependencies: # flutter pub run build_runner build --delete-conflicting-outputs diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 151aca32c..81bdc0f53 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -7,6 +7,7 @@ #include "generated_plugin_registrant.h" #include +#include #include #include #include @@ -18,6 +19,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { BitsdojoWindowPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("BitsdojoWindowPlugin")); + FirebaseCorePluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FirebaseCorePluginCApi")); IsarFlutterLibsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("IsarFlutterLibsPlugin")); LocalAuthPluginRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 6e7d68d41..1e8ddda81 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -4,6 +4,7 @@ list(APPEND FLUTTER_PLUGIN_LIST bitsdojo_window_windows + firebase_core isar_flutter_libs local_auth_windows permission_handler_windows