mirror of
https://github.com/lichess-org/mobile.git
synced 2026-05-26 13:50:52 +00:00
Install crashlytics
This commit is contained in:
@@ -18,6 +18,7 @@ analyzer:
|
||||
- "**/*.g.dart"
|
||||
- "**/*.freezed.dart"
|
||||
- lib/src/styles/lichess_icons.dart
|
||||
- lib/firebase_options.dart
|
||||
errors:
|
||||
invalid_annotation_target: ignore
|
||||
plugins:
|
||||
|
||||
@@ -28,6 +28,10 @@ if (keystorePropertiesFile.exists()) {
|
||||
}
|
||||
|
||||
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"
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"project_info": {
|
||||
"project_number": "974101866555",
|
||||
"project_id": "lichessv2",
|
||||
"storage_bucket": "lichessv2.appspot.com"
|
||||
},
|
||||
"client": [
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:974101866555:android:91f3475b526b436bb8541e",
|
||||
"android_client_info": {
|
||||
"package_name": "org.lichess.mobileV2"
|
||||
}
|
||||
},
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "974101866555-om4jq3npgepplk0fihrldnhuso1gm7k0.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyDQI6NZ5CM8xpuq9jfM0-D4Tq6fYfsaSh0"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": [
|
||||
{
|
||||
"client_id": "974101866555-om4jq3npgepplk0fihrldnhuso1gm7k0.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
},
|
||||
{
|
||||
"client_id": "974101866555-8ag66ua0p0pn1ab7u982i58a9iubhbod.apps.googleusercontent.com",
|
||||
"client_type": 2,
|
||||
"ios_info": {
|
||||
"bundle_id": "org.lichess.mobileV2"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"configuration_version": "1"
|
||||
}
|
||||
@@ -7,6 +7,10 @@ buildscript {
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.1.2'
|
||||
// START: FlutterFire Configuration
|
||||
classpath 'com.google.gms:google-services:4.3.10'
|
||||
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1'
|
||||
// END: FlutterFire Configuration
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,47 @@ PODS:
|
||||
- connectivity_plus (0.0.1):
|
||||
- Flutter
|
||||
- ReachabilitySwift
|
||||
- Firebase/CoreOnly (10.7.0):
|
||||
- FirebaseCore (= 10.7.0)
|
||||
- Firebase/Crashlytics (10.7.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseCrashlytics (~> 10.7.0)
|
||||
- firebase_core (2.11.0):
|
||||
- Firebase/CoreOnly (= 10.7.0)
|
||||
- Flutter
|
||||
- firebase_crashlytics (3.2.0):
|
||||
- Firebase/Crashlytics (= 10.7.0)
|
||||
- firebase_core
|
||||
- Flutter
|
||||
- FirebaseCore (10.7.0):
|
||||
- FirebaseCoreInternal (~> 10.0)
|
||||
- GoogleUtilities/Environment (~> 7.8)
|
||||
- GoogleUtilities/Logger (~> 7.8)
|
||||
- FirebaseCoreExtension (10.9.0):
|
||||
- FirebaseCore (~> 10.0)
|
||||
- FirebaseCoreInternal (10.7.0):
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.8)"
|
||||
- FirebaseCrashlytics (10.7.0):
|
||||
- FirebaseCore (~> 10.5)
|
||||
- FirebaseInstallations (~> 10.0)
|
||||
- FirebaseSessions (~> 10.5)
|
||||
- GoogleDataTransport (~> 9.2)
|
||||
- GoogleUtilities/Environment (~> 7.8)
|
||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
||||
- PromisesObjC (~> 2.1)
|
||||
- FirebaseInstallations (10.7.0):
|
||||
- FirebaseCore (~> 10.0)
|
||||
- GoogleUtilities/Environment (~> 7.8)
|
||||
- GoogleUtilities/UserDefaults (~> 7.8)
|
||||
- PromisesObjC (~> 2.1)
|
||||
- FirebaseSessions (10.9.0):
|
||||
- FirebaseCore (~> 10.5)
|
||||
- FirebaseCoreExtension (~> 10.0)
|
||||
- FirebaseInstallations (~> 10.0)
|
||||
- GoogleDataTransport (~> 9.2)
|
||||
- GoogleUtilities/Environment (~> 7.10)
|
||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
||||
- PromisesSwift (~> 2.1)
|
||||
- Flutter (1.0.0)
|
||||
- flutter_appauth (0.0.1):
|
||||
- AppAuth (= 1.6.0)
|
||||
@@ -19,11 +60,30 @@ PODS:
|
||||
- FMDB (2.7.5):
|
||||
- FMDB/standard (= 2.7.5)
|
||||
- FMDB/standard (2.7.5)
|
||||
- GoogleDataTransport (9.2.2):
|
||||
- GoogleUtilities/Environment (~> 7.7)
|
||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
||||
- PromisesObjC (< 3.0, >= 1.2)
|
||||
- GoogleUtilities/Environment (7.11.1):
|
||||
- PromisesObjC (< 3.0, >= 1.2)
|
||||
- GoogleUtilities/Logger (7.11.1):
|
||||
- GoogleUtilities/Environment
|
||||
- "GoogleUtilities/NSData+zlib (7.11.1)"
|
||||
- GoogleUtilities/UserDefaults (7.11.1):
|
||||
- GoogleUtilities/Logger
|
||||
- nanopb (2.30909.0):
|
||||
- nanopb/decode (= 2.30909.0)
|
||||
- nanopb/encode (= 2.30909.0)
|
||||
- nanopb/decode (2.30909.0)
|
||||
- nanopb/encode (2.30909.0)
|
||||
- package_info_plus (0.4.5):
|
||||
- Flutter
|
||||
- path_provider_foundation (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- PromisesObjC (2.2.0)
|
||||
- PromisesSwift (2.2.0):
|
||||
- PromisesObjC (= 2.2.0)
|
||||
- ReachabilitySwift (5.0.0)
|
||||
- share_plus (0.0.1):
|
||||
- Flutter
|
||||
@@ -42,6 +102,8 @@ PODS:
|
||||
|
||||
DEPENDENCIES:
|
||||
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
|
||||
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
|
||||
- firebase_crashlytics (from `.symlinks/plugins/firebase_crashlytics/ios`)
|
||||
- Flutter (from `Flutter`)
|
||||
- flutter_appauth (from `.symlinks/plugins/flutter_appauth/ios`)
|
||||
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
|
||||
@@ -58,12 +120,28 @@ DEPENDENCIES:
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- AppAuth
|
||||
- Firebase
|
||||
- FirebaseCore
|
||||
- FirebaseCoreExtension
|
||||
- FirebaseCoreInternal
|
||||
- FirebaseCrashlytics
|
||||
- FirebaseInstallations
|
||||
- FirebaseSessions
|
||||
- FMDB
|
||||
- GoogleDataTransport
|
||||
- GoogleUtilities
|
||||
- nanopb
|
||||
- PromisesObjC
|
||||
- PromisesSwift
|
||||
- ReachabilitySwift
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
connectivity_plus:
|
||||
:path: ".symlinks/plugins/connectivity_plus/ios"
|
||||
firebase_core:
|
||||
:path: ".symlinks/plugins/firebase_core/ios"
|
||||
firebase_crashlytics:
|
||||
:path: ".symlinks/plugins/firebase_crashlytics/ios"
|
||||
Flutter:
|
||||
:path: Flutter
|
||||
flutter_appauth:
|
||||
@@ -92,13 +170,27 @@ EXTERNAL SOURCES:
|
||||
SPEC CHECKSUMS:
|
||||
AppAuth: 8fca6b5563a5baef2c04bee27538025e4ceb2add
|
||||
connectivity_plus: 413a8857dd5d9f1c399a39130850d02fe0feaf7e
|
||||
Firebase: 0219acf760880eeec8ce479895bd7767466d9f81
|
||||
firebase_core: dee76ded6c693fdb38b8ea39aef7129e32e587a3
|
||||
firebase_crashlytics: 450dc80dcb167d04714c147336dd04a7230d20e4
|
||||
FirebaseCore: e317665b9d744727a97e623edbbed009320afdd7
|
||||
FirebaseCoreExtension: d3e9bba2930a8033042112397cd9f006a1bb203d
|
||||
FirebaseCoreInternal: 8845798510aae74703467480f71ac613788d0696
|
||||
FirebaseCrashlytics: 35fdd1a433b31e28adcf5c8933f4c526691a1e0b
|
||||
FirebaseInstallations: 59c0e4c7a816a0f76710d83f77e5369b3e45eb96
|
||||
FirebaseSessions: 44a6782502eb279a214d4adca20891353278760c
|
||||
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
||||
flutter_appauth: 525652bda90e43ca5eb7ed748ecc106b79d1f5a1
|
||||
flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef
|
||||
flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be
|
||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||
GoogleDataTransport: 8378d1fa8ac49753ea6ce70d65a7cb70ce5f66e6
|
||||
GoogleUtilities: 9aa0ad5a7bc171f8bae016300bfcfa3fb8425749
|
||||
nanopb: b552cce312b6c8484180ef47159bc0f65a1f0431
|
||||
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
|
||||
path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9
|
||||
PromisesObjC: 09985d6d70fbe7878040aa746d78236e6946d2ef
|
||||
PromisesSwift: cf9eb58666a43bbe007302226e510b16c1e10959
|
||||
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
|
||||
share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68
|
||||
shared_preferences_foundation: 986fc17f3d3251412d18b0265f9c64113a8c2472
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
||||
C2F75327C3BF9CDCF3AB3FB9 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = D30EA23BD9D2932936A0A1CD /* GoogleService-Info.plist */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
@@ -45,6 +46,7 @@
|
||||
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
D30EA23BD9D2932936A0A1CD /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = "<group>"; };
|
||||
D82FEDCEE538AF328E5BC6D1 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
||||
DE46A6181315EEBBE774A7A7 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
@@ -80,6 +82,7 @@
|
||||
97C146EF1CF9000F007C117D /* Products */,
|
||||
F7DEDEB5E675E58B05C28E05 /* Pods */,
|
||||
9A4FA943AFDC088B6B1831BF /* Frameworks */,
|
||||
D30EA23BD9D2932936A0A1CD /* GoogleService-Info.plist */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
@@ -139,6 +142,7 @@
|
||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||
1584E18F136EB9BC694994CC /* [CP] Embed Pods Frameworks */,
|
||||
717702CEA8A8AD636294A34D /* [firebase_crashlytics] Crashlytics Upload Symbols */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@@ -191,6 +195,7 @@
|
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
|
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
|
||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
|
||||
C2F75327C3BF9CDCF3AB3FB9 /* GoogleService-Info.plist in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -229,6 +234,26 @@
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
|
||||
};
|
||||
717702CEA8A8AD636294A34D /* [firebase_crashlytics] Crashlytics Upload Symbols */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"\"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${TARGET_NAME}\"",
|
||||
"\"$(SRCROOT)/$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)\"",
|
||||
);
|
||||
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\" ";
|
||||
};
|
||||
87319253AF8B73E944EEC4D0 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CLIENT_ID</key>
|
||||
<string>974101866555-8ag66ua0p0pn1ab7u982i58a9iubhbod.apps.googleusercontent.com</string>
|
||||
<key>REVERSED_CLIENT_ID</key>
|
||||
<string>com.googleusercontent.apps.974101866555-8ag66ua0p0pn1ab7u982i58a9iubhbod</string>
|
||||
<key>API_KEY</key>
|
||||
<string>AIzaSyC48jXlu52bjsbINcl3ixrrMEAbDf1uh90</string>
|
||||
<key>GCM_SENDER_ID</key>
|
||||
<string>974101866555</string>
|
||||
<key>PLIST_VERSION</key>
|
||||
<string>1</string>
|
||||
<key>BUNDLE_ID</key>
|
||||
<string>org.lichess.mobileV2</string>
|
||||
<key>PROJECT_ID</key>
|
||||
<string>lichessv2</string>
|
||||
<key>STORAGE_BUCKET</key>
|
||||
<string>lichessv2.appspot.com</string>
|
||||
<key>IS_ADS_ENABLED</key>
|
||||
<false></false>
|
||||
<key>IS_ANALYTICS_ENABLED</key>
|
||||
<false></false>
|
||||
<key>IS_APPINVITE_ENABLED</key>
|
||||
<true></true>
|
||||
<key>IS_GCM_ENABLED</key>
|
||||
<true></true>
|
||||
<key>IS_SIGNIN_ENABLED</key>
|
||||
<true></true>
|
||||
<key>GOOGLE_APP_ID</key>
|
||||
<string>1:974101866555:ios:1974acbdbcbfbe0eb8541e</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"file_generated_by": "FlutterFire CLI",
|
||||
"purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory",
|
||||
"GOOGLE_APP_ID": "1:974101866555:ios:1974acbdbcbfbe0eb8541e",
|
||||
"FIREBASE_PROJECT_ID": "lichessv2",
|
||||
"GCM_SENDER_ID": "974101866555"
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
// File generated by FlutterFire CLI.
|
||||
// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members
|
||||
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
|
||||
import 'package:flutter/foundation.dart'
|
||||
show defaultTargetPlatform, kIsWeb, TargetPlatform;
|
||||
|
||||
/// Default [FirebaseOptions] for use with your Firebase apps.
|
||||
///
|
||||
/// Example:
|
||||
/// ```dart
|
||||
/// import 'firebase_options.dart';
|
||||
/// // ...
|
||||
/// await Firebase.initializeApp(
|
||||
/// options: DefaultFirebaseOptions.currentPlatform,
|
||||
/// );
|
||||
/// ```
|
||||
class DefaultFirebaseOptions {
|
||||
static FirebaseOptions get currentPlatform {
|
||||
if (kIsWeb) {
|
||||
throw UnsupportedError(
|
||||
'DefaultFirebaseOptions have not been configured for web - '
|
||||
'you can reconfigure this by running the FlutterFire CLI again.',
|
||||
);
|
||||
}
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.android:
|
||||
return android;
|
||||
case TargetPlatform.iOS:
|
||||
return ios;
|
||||
case TargetPlatform.macOS:
|
||||
throw UnsupportedError(
|
||||
'DefaultFirebaseOptions have not been configured for macos - '
|
||||
'you can reconfigure this by running the FlutterFire CLI again.',
|
||||
);
|
||||
case TargetPlatform.windows:
|
||||
throw UnsupportedError(
|
||||
'DefaultFirebaseOptions have not been configured for windows - '
|
||||
'you can reconfigure this by running the FlutterFire CLI again.',
|
||||
);
|
||||
case TargetPlatform.linux:
|
||||
throw UnsupportedError(
|
||||
'DefaultFirebaseOptions have not been configured for linux - '
|
||||
'you can reconfigure this by running the FlutterFire CLI again.',
|
||||
);
|
||||
default:
|
||||
throw UnsupportedError(
|
||||
'DefaultFirebaseOptions are not supported for this platform.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static const FirebaseOptions android = FirebaseOptions(
|
||||
apiKey: 'AIzaSyDQI6NZ5CM8xpuq9jfM0-D4Tq6fYfsaSh0',
|
||||
appId: '1:974101866555:android:91f3475b526b436bb8541e',
|
||||
messagingSenderId: '974101866555',
|
||||
projectId: 'lichessv2',
|
||||
storageBucket: 'lichessv2.appspot.com',
|
||||
);
|
||||
|
||||
static const FirebaseOptions ios = FirebaseOptions(
|
||||
apiKey: 'AIzaSyC48jXlu52bjsbINcl3ixrrMEAbDf1uh90',
|
||||
appId: '1:974101866555:ios:1974acbdbcbfbe0eb8541e',
|
||||
messagingSenderId: '974101866555',
|
||||
projectId: 'lichessv2',
|
||||
storageBucket: 'lichessv2.appspot.com',
|
||||
iosClientId: '974101866555-8ag66ua0p0pn1ab7u982i58a9iubhbod.apps.googleusercontent.com',
|
||||
iosBundleId: 'org.lichess.mobileV2',
|
||||
);
|
||||
}
|
||||
@@ -5,6 +5,9 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:flutter_native_splash/flutter_native_splash.dart';
|
||||
import 'package:firebase_core/firebase_core.dart';
|
||||
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
|
||||
import 'firebase_options.dart';
|
||||
|
||||
import 'src/constants.dart';
|
||||
import 'src/app.dart';
|
||||
@@ -28,6 +31,18 @@ void main() async {
|
||||
}
|
||||
|
||||
final widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
// Crashlytics setup
|
||||
await Firebase.initializeApp(
|
||||
options: DefaultFirebaseOptions.currentPlatform,
|
||||
);
|
||||
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError;
|
||||
// Pass all uncaught asynchronous errors that aren't handled by the Flutter framework to Crashlytics
|
||||
PlatformDispatcher.instance.onError = (error, stack) {
|
||||
FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
|
||||
return true;
|
||||
};
|
||||
|
||||
FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
|
||||
|
||||
if (defaultTargetPlatform == TargetPlatform.android) {
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
part 'crashlytics.g.dart';
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
FirebaseCrashlytics crashlytics(CrashlyticsRef ref) {
|
||||
return FirebaseCrashlytics.instance;
|
||||
}
|
||||
@@ -8,8 +8,10 @@ import 'package:result_extensions/result_extensions.dart';
|
||||
import 'package:http/retry.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
|
||||
|
||||
import 'package:lichess_mobile/src/http_client.dart';
|
||||
import 'package:lichess_mobile/src/crashlytics.dart';
|
||||
import 'package:lichess_mobile/src/model/auth/auth_controller.dart';
|
||||
import 'package:lichess_mobile/src/model/user/user.dart';
|
||||
import 'package:lichess_mobile/src/model/common/errors.dart';
|
||||
@@ -20,6 +22,7 @@ part 'auth_client.g.dart';
|
||||
@Riverpod(keepAlive: true)
|
||||
AuthClient authClient(AuthClientRef ref) {
|
||||
final httpClient = ref.watch(httpClientProvider);
|
||||
final crashlytics = ref.watch(crashlyticsProvider);
|
||||
final logger = Logger('AuthClient');
|
||||
final insideAuthClient = _AuthClient(
|
||||
ref,
|
||||
@@ -29,6 +32,7 @@ AuthClient authClient(AuthClientRef ref) {
|
||||
final authClient = AuthClient(
|
||||
logger,
|
||||
insideAuthClient,
|
||||
crashlytics,
|
||||
);
|
||||
ref.onDispose(() {
|
||||
authClient.close();
|
||||
@@ -47,7 +51,8 @@ AuthClient authClient(AuthClientRef ref) {
|
||||
class AuthClient {
|
||||
AuthClient(
|
||||
this._log,
|
||||
this._client, {
|
||||
this._client,
|
||||
this._crashlytics, {
|
||||
List<Duration> retryDelays = defaultRetries,
|
||||
}) : _retryClient = RetryClient.withDelays(
|
||||
_client,
|
||||
@@ -65,6 +70,7 @@ class AuthClient {
|
||||
final Client _client;
|
||||
final RetryClient _retryClient;
|
||||
final RetryClient _retryClientOnError;
|
||||
final FirebaseCrashlytics _crashlytics;
|
||||
|
||||
/// Makes app user agent
|
||||
static String userAgent(PackageInfo info, LightUser? user) =>
|
||||
@@ -80,6 +86,11 @@ class AuthClient {
|
||||
.get(url, headers: headers),
|
||||
).mapError((error, stackTrace) {
|
||||
_log.severe('Request error', error, stackTrace);
|
||||
_crashlytics.recordError(
|
||||
error,
|
||||
stackTrace,
|
||||
reason: 'a non-fatal http request error',
|
||||
);
|
||||
return GenericIOException();
|
||||
}).flatMap(
|
||||
(response) => _validateResponseStatusResult('GET', url, response),
|
||||
@@ -97,6 +108,11 @@ class AuthClient {
|
||||
.post(url, headers: headers, body: body, encoding: encoding),
|
||||
).mapError((error, stackTrace) {
|
||||
_log.severe('Request error', error, stackTrace);
|
||||
_crashlytics.recordError(
|
||||
error,
|
||||
stackTrace,
|
||||
reason: 'a non-fatal http request error',
|
||||
);
|
||||
return GenericIOException();
|
||||
}).flatMap(
|
||||
(response) => _validateResponseStatusResult('POST', url, response),
|
||||
|
||||
@@ -9,6 +9,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "58.0.0"
|
||||
_flutterfire_internals:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: _flutterfire_internals
|
||||
sha256: "867b77e2367bc502dcd4d5a66302615409f04eb20ed82ba1c0ba073f9107e018"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -403,6 +411,46 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.1.4"
|
||||
firebase_core:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_core
|
||||
sha256: dcf54c170c5371ad0e79229d0fb372c58262ae0968b7de222bf28e51dd236be0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.11.0"
|
||||
firebase_core_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_core_platform_interface
|
||||
sha256: ae79f335f6c7f2dadb00c98c429da2ca905d265e0225fb5e7dfa62ac3accad48
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.7.0"
|
||||
firebase_core_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_core_web
|
||||
sha256: e57ef862257a0d977c1308d02e2fbb9b68525e6d85711b08f3df8cec836fb444
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
firebase_crashlytics:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_crashlytics
|
||||
sha256: e8424f75c0fd466a6ae4d069b313ec84133ef275c00a5a3a416b75b99fb3e831
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.0"
|
||||
firebase_crashlytics_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_crashlytics_platform_interface
|
||||
sha256: "381e28f33d5255a698ac7755c3c4fdff42382be0154f375564e6852aa46f9d8f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.5.0"
|
||||
fixnum:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -66,6 +66,8 @@ dependencies:
|
||||
url: https://github.com/lichess-org/dart-stockfish.git
|
||||
ref: 274cf52e637e9a663d226ec31cc0b24e639cb615
|
||||
easy_debounce: ^2.0.3
|
||||
firebase_crashlytics: ^3.2.0
|
||||
firebase_core: ^2.11.0
|
||||
|
||||
dev_dependencies:
|
||||
build_runner: ^2.3.2
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:firebase_core/firebase_core.dart';
|
||||
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
|
||||
|
||||
// ignore_for_file: avoid_implementing_value_types
|
||||
// ignore_for_file: type_annotate_public_apis
|
||||
// ignore_for_file: strict_raw_type
|
||||
|
||||
class MockFirebaseApp extends Mock implements FirebaseApp {}
|
||||
|
||||
class FakeCrashlytics implements FirebaseCrashlytics {
|
||||
@override
|
||||
FirebaseApp app = MockFirebaseApp();
|
||||
|
||||
@override
|
||||
Future<bool> checkForUnsentReports() async {
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
void crash() {}
|
||||
|
||||
@override
|
||||
Future<void> deleteUnsentReports() async {}
|
||||
|
||||
@override
|
||||
Future<bool> didCrashOnPreviousExecution() async {
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
// TODO: implement isCrashlyticsCollectionEnabled
|
||||
bool get isCrashlyticsCollectionEnabled => false;
|
||||
|
||||
@override
|
||||
Future<void> log(String message) async {}
|
||||
|
||||
@override
|
||||
// TODO: implement pluginConstants
|
||||
Map get pluginConstants => {};
|
||||
|
||||
@override
|
||||
Future<void> recordError(
|
||||
exception,
|
||||
StackTrace? stack, {
|
||||
reason,
|
||||
Iterable<Object> information = const [],
|
||||
bool? printDetails,
|
||||
bool fatal = false,
|
||||
}) async {}
|
||||
|
||||
@override
|
||||
Future<void> recordFlutterError(
|
||||
FlutterErrorDetails flutterErrorDetails, {
|
||||
bool fatal = false,
|
||||
}) async {}
|
||||
|
||||
@override
|
||||
Future<void> recordFlutterFatalError(
|
||||
FlutterErrorDetails flutterErrorDetails,
|
||||
) async {}
|
||||
|
||||
@override
|
||||
Future<void> sendUnsentReports() async {}
|
||||
|
||||
@override
|
||||
Future<void> setCrashlyticsCollectionEnabled(bool enabled) async {}
|
||||
|
||||
@override
|
||||
Future<void> setCustomKey(String key, Object value) async {}
|
||||
|
||||
@override
|
||||
Future<void> setUserIdentifier(String identifier) async {}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import 'package:mocktail/mocktail.dart';
|
||||
|
||||
import 'package:lichess_mobile/src/model/common/errors.dart';
|
||||
import 'package:lichess_mobile/src/model/auth/auth_client.dart';
|
||||
import '../../fake_crashlytics.dart';
|
||||
|
||||
class MockLogger extends Mock implements Logger {}
|
||||
|
||||
@@ -15,6 +16,7 @@ class MockClient extends Mock implements http.Client {}
|
||||
|
||||
void main() {
|
||||
final mockLogger = MockLogger();
|
||||
final mockCrashlytics = FakeCrashlytics();
|
||||
|
||||
setUpAll(() {
|
||||
registerFallbackValue(http.Request('GET', Uri.parse('http://api.test')));
|
||||
@@ -22,7 +24,7 @@ void main() {
|
||||
|
||||
group('AuthClient non stream', () {
|
||||
test('ValueResult responses are returned as success', () async {
|
||||
final apiClient = AuthClient(mockLogger, FakeClient());
|
||||
final apiClient = AuthClient(mockLogger, FakeClient(), mockCrashlytics);
|
||||
|
||||
for (final method in [apiClient.get, apiClient.post, apiClient.delete]) {
|
||||
expect(
|
||||
@@ -43,7 +45,7 @@ void main() {
|
||||
});
|
||||
|
||||
test('error responses are returned as error', () async {
|
||||
final apiClient = AuthClient(mockLogger, FakeClient());
|
||||
final apiClient = AuthClient(mockLogger, FakeClient(), mockCrashlytics);
|
||||
|
||||
for (final method in [apiClient.get, apiClient.post, apiClient.delete]) {
|
||||
expect(
|
||||
@@ -84,7 +86,7 @@ void main() {
|
||||
});
|
||||
|
||||
test('catches socket error', () async {
|
||||
final apiClient = AuthClient(mockLogger, FakeClient());
|
||||
final apiClient = AuthClient(mockLogger, FakeClient(), mockCrashlytics);
|
||||
for (final method in [apiClient.get, apiClient.post, apiClient.delete]) {
|
||||
final resp = await method
|
||||
.call(Uri.parse('http://api.test/will/throw/socket/exception'));
|
||||
@@ -94,7 +96,7 @@ void main() {
|
||||
|
||||
test('retry on error by default', () async {
|
||||
final mockClient = MockClient();
|
||||
final apiClient = AuthClient(mockLogger, mockClient);
|
||||
final apiClient = AuthClient(mockLogger, mockClient, mockCrashlytics);
|
||||
|
||||
int retries = 3;
|
||||
|
||||
@@ -117,7 +119,7 @@ void main() {
|
||||
|
||||
group('AuthClient stream', () {
|
||||
test('response is returned when ValueResult', () async {
|
||||
final apiClient = AuthClient(mockLogger, FakeClient());
|
||||
final apiClient = AuthClient(mockLogger, FakeClient(), mockCrashlytics);
|
||||
|
||||
expect(
|
||||
await apiClient.stream(Uri.parse('http://api.test/will/return/200')),
|
||||
@@ -136,7 +138,7 @@ void main() {
|
||||
});
|
||||
|
||||
test('throws on error', () {
|
||||
final apiClient = AuthClient(mockLogger, FakeClient());
|
||||
final apiClient = AuthClient(mockLogger, FakeClient(), mockCrashlytics);
|
||||
|
||||
expect(
|
||||
() => apiClient.stream(Uri.parse('http://api.test/will/return/401')),
|
||||
@@ -165,7 +167,7 @@ void main() {
|
||||
});
|
||||
|
||||
test('socket error is a GenericIOException', () {
|
||||
final apiClient = AuthClient(mockLogger, FakeClient());
|
||||
final apiClient = AuthClient(mockLogger, FakeClient(), mockCrashlytics);
|
||||
|
||||
expect(
|
||||
() => apiClient
|
||||
|
||||
@@ -14,6 +14,7 @@ import 'package:mocktail/mocktail.dart';
|
||||
import 'package:soundpool/soundpool.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
|
||||
import 'package:lichess_mobile/src/crashlytics.dart';
|
||||
import 'package:lichess_mobile/src/app_dependencies.dart';
|
||||
import 'package:lichess_mobile/src/db/shared_preferences.dart';
|
||||
import 'package:lichess_mobile/src/model/common/service/sound_service.dart';
|
||||
@@ -23,6 +24,7 @@ import 'package:lichess_mobile/src/model/auth/user_session.dart';
|
||||
import './common/fake_sound_service.dart';
|
||||
import './model/auth/fake_auth_repository.dart';
|
||||
import './model/auth/fake_session_storage.dart';
|
||||
import './fake_crashlytics.dart';
|
||||
|
||||
class MockSoundPool extends Mock implements Soundpool {}
|
||||
|
||||
@@ -57,6 +59,8 @@ Future<Widget> buildTestApp(
|
||||
|
||||
return ProviderScope(
|
||||
overrides: [
|
||||
// ignore: scoped_providers_should_specify_dependencies
|
||||
crashlyticsProvider.overrideWithValue(FakeCrashlytics()),
|
||||
// ignore: scoped_providers_should_specify_dependencies
|
||||
soundServiceProvider.overrideWithValue(FakeSoundService()),
|
||||
// ignore: scoped_providers_should_specify_dependencies
|
||||
|
||||
@@ -9,6 +9,7 @@ import 'package:mocktail/mocktail.dart';
|
||||
import 'package:soundpool/soundpool.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
|
||||
import 'package:lichess_mobile/src/crashlytics.dart';
|
||||
import 'package:lichess_mobile/src/app_dependencies.dart';
|
||||
import 'package:lichess_mobile/src/db/shared_preferences.dart';
|
||||
import 'package:lichess_mobile/src/model/common/service/sound_service.dart';
|
||||
@@ -18,6 +19,7 @@ import 'package:lichess_mobile/src/model/auth/session_storage.dart';
|
||||
import './common/fake_sound_service.dart';
|
||||
import './model/auth/fake_auth_repository.dart';
|
||||
import './model/auth/fake_session_storage.dart';
|
||||
import './fake_crashlytics.dart';
|
||||
|
||||
class MockSoundPool extends Mock implements Soundpool {}
|
||||
|
||||
@@ -41,6 +43,7 @@ Future<ProviderContainer> makeContainer({
|
||||
|
||||
final container = ProviderContainer(
|
||||
overrides: [
|
||||
crashlyticsProvider.overrideWithValue(FakeCrashlytics()),
|
||||
soundServiceProvider.overrideWithValue(FakeSoundService()),
|
||||
sharedPreferencesProvider.overrideWithValue(sharedPreferences),
|
||||
authRepositoryProvider.overrideWithValue(FakeAuthRepository()),
|
||||
|
||||
Reference in New Issue
Block a user