From dfec7d60592abe0a5c6523e13feabffb8b03020b Mon Sep 17 00:00:00 2001 From: Mike Diarmid Date: Fri, 29 Apr 2022 11:17:19 +0100 Subject: [PATCH 1/4] feat(crashlytics): add support for on-demand exception reporting (#8540) Co-authored-by: Elena Doty Co-authored-by: Russell Wheatley --- .../firebase_crashlytics/android/build.gradle | 5 +- .../FlutterFirebaseCrashlyticsInternal.java | 18 + .../FlutterFirebaseCrashlyticsPlugin.java | 27 +- .../example/android/app/build.gradle | 5 +- .../example/android/app/google-services.json | 456 +----------------- .../example/android/build.gradle | 4 +- .../example/lib/firebase_options.dart | 79 +++ .../example/lib/main.dart | 29 +- .../macos/Runner.xcodeproj/project.pbxproj | 35 +- .../macos/Runner/GoogleService-Info.plist | 28 +- .../ios/Classes/Crashlytics_Platform.h | 2 + .../ios/Classes/ExceptionModel_Platform.h | 28 ++ .../Classes/FLTFirebaseCrashlyticsPlugin.m | 15 +- .../lib/src/firebase_crashlytics.dart | 7 +- 14 files changed, 224 insertions(+), 514 deletions(-) create mode 100644 packages/firebase_crashlytics/firebase_crashlytics/android/src/main/java/com/google/firebase/crashlytics/FlutterFirebaseCrashlyticsInternal.java create mode 100644 packages/firebase_crashlytics/firebase_crashlytics/example/lib/firebase_options.dart create mode 100644 packages/firebase_crashlytics/firebase_crashlytics/ios/Classes/ExceptionModel_Platform.h diff --git a/packages/firebase_crashlytics/firebase_crashlytics/android/build.gradle b/packages/firebase_crashlytics/firebase_crashlytics/android/build.gradle index 7e7610f01c51..21205eec83de 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics/android/build.gradle +++ b/packages/firebase_crashlytics/firebase_crashlytics/android/build.gradle @@ -20,7 +20,6 @@ rootProject.allprojects { } apply plugin: 'com.android.library' - def firebaseCoreProject = findProject(':firebase_core') if (firebaseCoreProject == null) { throw new GradleException('Could not find the firebase_core FlutterFire plugin, have you added it as a dependency in your pubspec?') @@ -52,7 +51,9 @@ android { dependencies { implementation platform("com.google.firebase:firebase-bom:${getRootProjectExtOrCoreProperty("FirebaseSDKVersion", firebaseCoreProject)}") - implementation 'com.google.firebase:firebase-crashlytics' + // TODO remove specific version and fallback to BoM once 18.2.10 is available in a BoM release + implementation 'com.google.firebase:firebase-crashlytics:18.2.10' + // implementation 'com.google.firebase:firebase-crashlytics' implementation 'androidx.annotation:annotation:1.1.0' } diff --git a/packages/firebase_crashlytics/firebase_crashlytics/android/src/main/java/com/google/firebase/crashlytics/FlutterFirebaseCrashlyticsInternal.java b/packages/firebase_crashlytics/firebase_crashlytics/android/src/main/java/com/google/firebase/crashlytics/FlutterFirebaseCrashlyticsInternal.java new file mode 100644 index 000000000000..30f4444333e1 --- /dev/null +++ b/packages/firebase_crashlytics/firebase_crashlytics/android/src/main/java/com/google/firebase/crashlytics/FlutterFirebaseCrashlyticsInternal.java @@ -0,0 +1,18 @@ +package com.google.firebase.crashlytics; + +import android.annotation.SuppressLint; +import com.google.firebase.crashlytics.internal.Logger; + +/** @hide */ +public final class FlutterFirebaseCrashlyticsInternal { + @SuppressLint("VisibleForTests") + public static void recordFatalException(Throwable throwable) { + if (throwable == null) { + Logger.getLogger().w("A null value was passed to recordFatalException. Ignoring."); + return; + } + FirebaseCrashlytics.getInstance().core.logFatalException(throwable); + } + + private FlutterFirebaseCrashlyticsInternal() {} +} diff --git a/packages/firebase_crashlytics/firebase_crashlytics/android/src/main/java/io/flutter/plugins/firebase/crashlytics/FlutterFirebaseCrashlyticsPlugin.java b/packages/firebase_crashlytics/firebase_crashlytics/android/src/main/java/io/flutter/plugins/firebase/crashlytics/FlutterFirebaseCrashlyticsPlugin.java index b48e015a7ecb..580efbd69f98 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics/android/src/main/java/io/flutter/plugins/firebase/crashlytics/FlutterFirebaseCrashlyticsPlugin.java +++ b/packages/firebase_crashlytics/firebase_crashlytics/android/src/main/java/io/flutter/plugins/firebase/crashlytics/FlutterFirebaseCrashlyticsPlugin.java @@ -6,16 +6,14 @@ import android.content.Context; import android.content.SharedPreferences; -import android.os.Bundle; import android.os.Handler; import android.util.Log; import androidx.annotation.NonNull; import com.google.android.gms.tasks.Task; import com.google.android.gms.tasks.Tasks; import com.google.firebase.FirebaseApp; -import com.google.firebase.analytics.connector.AnalyticsConnector; import com.google.firebase.crashlytics.FirebaseCrashlytics; -import com.google.firebase.crashlytics.internal.analytics.CrashlyticsOriginAnalyticsEventLogger; +import com.google.firebase.crashlytics.FlutterFirebaseCrashlyticsInternal; import io.flutter.embedding.engine.plugins.FlutterPlugin; import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.MethodCall; @@ -114,7 +112,7 @@ private Task recordError(final Map arguments) { final String reason = (String) arguments.get(Constants.REASON); final String information = (String) Objects.requireNonNull(arguments.get(Constants.INFORMATION)); - final boolean fatal = (boolean) arguments.get(Constants.FATAL); + final boolean fatal = (boolean) Objects.requireNonNull(arguments.get(Constants.FATAL)); Exception exception; if (reason != null) { @@ -126,21 +124,6 @@ private Task recordError(final Map arguments) { exception = new FlutterError(dartExceptionMessage); } - if (fatal) { - AnalyticsConnector connector = FirebaseApp.getInstance().get(AnalyticsConnector.class); - CrashlyticsOriginAnalyticsEventLogger analyticsEventLogger = - new CrashlyticsOriginAnalyticsEventLogger(connector); - - Bundle params = new Bundle(); - long unixTime = System.currentTimeMillis() / 1000; - - params.putInt(Constants.FATAL, 1); - params.putLong(Constants.TIMESTAMP, unixTime); - - crashlytics.setCustomKey(Constants.CRASH_EVENT_KEY, unixTime); - analyticsEventLogger.logEvent(Constants.FIREBASE_APPLICATION_EXCEPTION, params); - } - crashlytics.setCustomKey(Constants.FLUTTER_ERROR_EXCEPTION, dartExceptionMessage); final List elements = new ArrayList<>(); @@ -162,7 +145,11 @@ private Task recordError(final Map arguments) { crashlytics.log(information); } - crashlytics.recordException(exception); + if (fatal) { + FlutterFirebaseCrashlyticsInternal.recordFatalException(exception); + } else { + crashlytics.recordException(exception); + } return null; }); } diff --git a/packages/firebase_crashlytics/firebase_crashlytics/example/android/app/build.gradle b/packages/firebase_crashlytics/firebase_crashlytics/example/android/app/build.gradle index de81ea7e8bc7..7f6b32f49661 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics/example/android/app/build.gradle +++ b/packages/firebase_crashlytics/firebase_crashlytics/example/android/app/build.gradle @@ -25,7 +25,7 @@ apply plugin: 'com.android.application' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 29 + compileSdkVersion 31 lintOptions { disable 'InvalidPackage' @@ -60,4 +60,5 @@ dependencies { androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' } -apply plugin: 'com.google.firebase.crashlytics' +apply plugin: 'com.google.gms.google-services' +apply plugin: 'com.google.firebase.crashlytics' \ No newline at end of file diff --git a/packages/firebase_crashlytics/firebase_crashlytics/example/android/app/google-services.json b/packages/firebase_crashlytics/firebase_crashlytics/example/android/app/google-services.json index d7215ee2004b..71e2bfecccc8 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics/example/android/app/google-services.json +++ b/packages/firebase_crashlytics/firebase_crashlytics/example/android/app/google-services.json @@ -1,277 +1,49 @@ { "project_info": { - "project_number": "448618578101", - "firebase_url": "https://react-native-firebase-testing.firebaseio.com", - "project_id": "react-native-firebase-testing", - "storage_bucket": "react-native-firebase-testing.appspot.com" + "project_number": "406099696497", + "firebase_url": "https://flutterfire-e2e-tests-default-rtdb.europe-west1.firebasedatabase.app", + "project_id": "flutterfire-e2e-tests", + "storage_bucket": "flutterfire-e2e-tests.appspot.com" }, "client": [ { "client_info": { - "mobilesdk_app_id": "1:448618578101:android:e708991417cc7542ac3efc", + "mobilesdk_app_id": "1:406099696497:android:7ca3394493cc601a3574d0", "android_client_info": { - "package_name": "com.example.testapp" + "package_name": "io.flutter.plugins.firebase.functions.example" } }, "oauth_client": [ { - "client_id": "448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com", - "client_type": 3 - } - ], - "api_key": [ - { - "current_key": "AIzaSyCuu4tbv9CwwTudNOweMNstzZHIDBhgJxA" - } - ], - "services": { - "appinvite_service": { - "other_platform_oauth_client": [ - { - "client_id": "448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com", - "client_type": 3 - }, - { - "client_id": "448618578101-54jhd806d0tr4vkgode0b4fi8iruvjpn.apps.googleusercontent.com", - "client_type": 2, - "ios_info": { - "bundle_id": "io.flutter.plugins.firebase.crashlytics.firebaseCrashlyticsExample" - } - } - ] - } - } - }, - { - "client_info": { - "mobilesdk_app_id": "1:448618578101:android:cc6c1dc7a65cc83c", - "android_client_info": { - "package_name": "com.invertase.testing" - } - }, - "oauth_client": [ - { - "client_id": "448618578101-h0o9b94jnhcoal2qgjn7s7ckkc2n7okq.apps.googleusercontent.com", + "client_id": "406099696497-tvtvuiqogct1gs1s6lh114jeps7hpjm5.apps.googleusercontent.com", "client_type": 1, "android_info": { - "package_name": "com.invertase.testing", + "package_name": "io.flutter.plugins.firebase.functions.example", "certificate_hash": "909ca1482ef022bbae45a2db6b6d05d807a4c4aa" } }, { - "client_id": "448618578101-gva3jv7cr8qquj04k0o7cni674j65kha.apps.googleusercontent.com", - "client_type": 1, - "android_info": { - "package_name": "com.invertase.testing", - "certificate_hash": "5e8f16062ea3cd2c4a0d547876baa6f38cabf625" - } - }, - { - "client_id": "448618578101-a9p7bj5jlakabp22fo3cbkj7nsmag24e.apps.googleusercontent.com", - "client_type": 1, - "android_info": { - "package_name": "com.invertase.testing", - "certificate_hash": "889b4292c735f371168a372cc7778992cd8a5052" - } - }, - { - "client_id": "448618578101-pdjje2lkv3p941e03hkrhfa7459cr2v8.apps.googleusercontent.com", - "client_type": 1, - "android_info": { - "package_name": "com.invertase.testing", - "certificate_hash": "992e468b990cc418f306d0131be61ecfad800ac1" - } - }, - { - "client_id": "448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com", - "client_type": 3 - } - ], - "api_key": [ - { - "current_key": "AIzaSyCuu4tbv9CwwTudNOweMNstzZHIDBhgJxA" - } - ], - "services": { - "appinvite_service": { - "other_platform_oauth_client": [ - { - "client_id": "448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com", - "client_type": 3 - }, - { - "client_id": "448618578101-54jhd806d0tr4vkgode0b4fi8iruvjpn.apps.googleusercontent.com", - "client_type": 2, - "ios_info": { - "bundle_id": "io.flutter.plugins.firebase.crashlytics.firebaseCrashlyticsExample" - } - } - ] - } - } - }, - { - "client_info": { - "mobilesdk_app_id": "1:448618578101:android:cc5ce91648e65dbeac3efc", - "android_client_info": { - "package_name": "com.notifeetestapp" - } - }, - "oauth_client": [ - { - "client_id": "448618578101-j9nluebtat700ua550esfvaf64gbo5l5.apps.googleusercontent.com", - "client_type": 1, - "android_info": { - "package_name": "com.notifeetestapp", - "certificate_hash": "5e8f16062ea3cd2c4a0d547876baa6f38cabf625" - } - }, - { - "client_id": "448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com", - "client_type": 3 - } - ], - "api_key": [ - { - "current_key": "AIzaSyCuu4tbv9CwwTudNOweMNstzZHIDBhgJxA" - } - ], - "services": { - "appinvite_service": { - "other_platform_oauth_client": [ - { - "client_id": "448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com", - "client_type": 3 - }, - { - "client_id": "448618578101-54jhd806d0tr4vkgode0b4fi8iruvjpn.apps.googleusercontent.com", - "client_type": 2, - "ios_info": { - "bundle_id": "io.flutter.plugins.firebase.crashlytics.firebaseCrashlyticsExample" - } - } - ] - } - } - }, - { - "client_info": { - "mobilesdk_app_id": "1:448618578101:android:6aa085e64d694703ac3efc", - "android_client_info": { - "package_name": "com.rnfbdemo" - } - }, - "oauth_client": [ - { - "client_id": "448618578101-a8tk83htomfvrelhu71j93safubvipdj.apps.googleusercontent.com", - "client_type": 1, - "android_info": { - "package_name": "com.rnfbdemo", - "certificate_hash": "909ca1482ef022bbae45a2db6b6d05d807a4c4aa" - } - }, - { - "client_id": "448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com", - "client_type": 3 - } - ], - "api_key": [ - { - "current_key": "AIzaSyCuu4tbv9CwwTudNOweMNstzZHIDBhgJxA" - } - ], - "services": { - "appinvite_service": { - "other_platform_oauth_client": [ - { - "client_id": "448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com", - "client_type": 3 - }, - { - "client_id": "448618578101-54jhd806d0tr4vkgode0b4fi8iruvjpn.apps.googleusercontent.com", - "client_type": 2, - "ios_info": { - "bundle_id": "io.flutter.plugins.firebase.crashlytics.firebaseCrashlyticsExample" - } - } - ] - } - } - }, - { - "client_info": { - "mobilesdk_app_id": "1:448618578101:android:c017beb5f26b66fcac3efc", - "android_client_info": { - "package_name": "com.testapp" - } - }, - "oauth_client": [ - { - "client_id": "448618578101-q1ffje1ttluf8vfhi4aa50pag231q9dt.apps.googleusercontent.com", - "client_type": 1, - "android_info": { - "package_name": "com.testapp", - "certificate_hash": "909ca1482ef022bbae45a2db6b6d05d807a4c4aa" - } - }, - { - "client_id": "448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com", - "client_type": 3 - } - ], - "api_key": [ - { - "current_key": "AIzaSyCuu4tbv9CwwTudNOweMNstzZHIDBhgJxA" - } - ], - "services": { - "appinvite_service": { - "other_platform_oauth_client": [ - { - "client_id": "448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com", - "client_type": 3 - }, - { - "client_id": "448618578101-54jhd806d0tr4vkgode0b4fi8iruvjpn.apps.googleusercontent.com", - "client_type": 2, - "ios_info": { - "bundle_id": "io.flutter.plugins.firebase.crashlytics.firebaseCrashlyticsExample" - } - } - ] - } - } - }, - { - "client_info": { - "mobilesdk_app_id": "1:448618578101:android:6bf0706c1f27114dac3efc", - "android_client_info": { - "package_name": "io.flutter.plugins.firebase.cloudfunctions.cloudfunctionsexample" - } - }, - "oauth_client": [ - { - "client_id": "448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com", + "client_id": "406099696497-a12gakvts4epfk5pkio7dphc1anjiggc.apps.googleusercontent.com", "client_type": 3 } ], "api_key": [ { - "current_key": "AIzaSyCuu4tbv9CwwTudNOweMNstzZHIDBhgJxA" + "current_key": "AIzaSyCdRjCVZlhrq72RuEklEyyxYlBRCYhI2Sw" } ], "services": { "appinvite_service": { "other_platform_oauth_client": [ { - "client_id": "448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com", + "client_id": "406099696497-a12gakvts4epfk5pkio7dphc1anjiggc.apps.googleusercontent.com", "client_type": 3 }, { - "client_id": "448618578101-54jhd806d0tr4vkgode0b4fi8iruvjpn.apps.googleusercontent.com", + "client_id": "406099696497-epk7902e2mb4pj4i4gcotk4q7dp2i9h3.apps.googleusercontent.com", "client_type": 2, "ios_info": { - "bundle_id": "io.flutter.plugins.firebase.crashlytics.firebaseCrashlyticsExample" + "bundle_id": "io.flutter.plugins.firebase.crashlytics.example" } } ] @@ -280,34 +52,34 @@ }, { "client_info": { - "mobilesdk_app_id": "1:448618578101:android:5cc04a661d27c405ac3efc", + "mobilesdk_app_id": "1:406099696497:android:0d4ed619c031c0ac3574d0", "android_client_info": { - "package_name": "io.flutter.plugins.firebase.crashlytics.firebasecrashlyticsexample" + "package_name": "io.flutter.plugins.firebase.tests" } }, "oauth_client": [ { - "client_id": "448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com", + "client_id": "406099696497-a12gakvts4epfk5pkio7dphc1anjiggc.apps.googleusercontent.com", "client_type": 3 } ], "api_key": [ { - "current_key": "AIzaSyCuu4tbv9CwwTudNOweMNstzZHIDBhgJxA" + "current_key": "AIzaSyCdRjCVZlhrq72RuEklEyyxYlBRCYhI2Sw" } ], "services": { "appinvite_service": { "other_platform_oauth_client": [ { - "client_id": "448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com", + "client_id": "406099696497-a12gakvts4epfk5pkio7dphc1anjiggc.apps.googleusercontent.com", "client_type": 3 }, { - "client_id": "448618578101-54jhd806d0tr4vkgode0b4fi8iruvjpn.apps.googleusercontent.com", + "client_id": "406099696497-epk7902e2mb4pj4i4gcotk4q7dp2i9h3.apps.googleusercontent.com", "client_type": 2, "ios_info": { - "bundle_id": "io.flutter.plugins.firebase.crashlytics.firebaseCrashlyticsExample" + "bundle_id": "io.flutter.plugins.firebase.crashlytics.example" } } ] @@ -316,210 +88,34 @@ }, { "client_info": { - "mobilesdk_app_id": "1:448618578101:android:3ad281c0067ccf97ac3efc", - "android_client_info": { - "package_name": "io.flutter.plugins.firebase.firestoreexample" - } - }, - "oauth_client": [ - { - "client_id": "448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com", - "client_type": 3 - } - ], - "api_key": [ - { - "current_key": "AIzaSyCuu4tbv9CwwTudNOweMNstzZHIDBhgJxA" - } - ], - "services": { - "appinvite_service": { - "other_platform_oauth_client": [ - { - "client_id": "448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com", - "client_type": 3 - }, - { - "client_id": "448618578101-54jhd806d0tr4vkgode0b4fi8iruvjpn.apps.googleusercontent.com", - "client_type": 2, - "ios_info": { - "bundle_id": "io.flutter.plugins.firebase.crashlytics.firebaseCrashlyticsExample" - } - } - ] - } - } - }, - { - "client_info": { - "mobilesdk_app_id": "1:448618578101:android:9d44a7b85d1ab0baac3efc", - "android_client_info": { - "package_name": "io.flutter.plugins.firebaseauthexample" - } - }, - "oauth_client": [ - { - "client_id": "448618578101-velutq65ok2dr5ohh0oi1q62irr920ss.apps.googleusercontent.com", - "client_type": 1, - "android_info": { - "package_name": "io.flutter.plugins.firebaseauthexample", - "certificate_hash": "29142b8612b4b6a0ba0fefd1dbf65ab565fb2cbd" - } - }, - { - "client_id": "448618578101-2brn4509s8513kjf9a0i6kvtb9qnght5.apps.googleusercontent.com", - "client_type": 1, - "android_info": { - "package_name": "io.flutter.plugins.firebaseauthexample", - "certificate_hash": "e1604565b51994d10886de1d91da9968dfec02ed" - } - }, - { - "client_id": "448618578101-2kqet2itdu42g0avs2v3fbsmtf6a45gg.apps.googleusercontent.com", - "client_type": 1, - "android_info": { - "package_name": "io.flutter.plugins.firebaseauthexample", - "certificate_hash": "939efbe8eaa5aaf50396b19fe980ef4a8df1c6e7" - } - }, - { - "client_id": "448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com", - "client_type": 3 - } - ], - "api_key": [ - { - "current_key": "AIzaSyCuu4tbv9CwwTudNOweMNstzZHIDBhgJxA" - } - ], - "services": { - "appinvite_service": { - "other_platform_oauth_client": [ - { - "client_id": "448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com", - "client_type": 3 - }, - { - "client_id": "448618578101-54jhd806d0tr4vkgode0b4fi8iruvjpn.apps.googleusercontent.com", - "client_type": 2, - "ios_info": { - "bundle_id": "io.flutter.plugins.firebase.crashlytics.firebaseCrashlyticsExample" - } - } - ] - } - } - }, - { - "client_info": { - "mobilesdk_app_id": "1:448618578101:android:29bf96f913c195f5ac3efc", + "mobilesdk_app_id": "1:406099696497:android:0f3f7bfe78b8b7103574d0", "android_client_info": { "package_name": "io.flutter.plugins.firebasecrashlyticsexample" } }, "oauth_client": [ { - "client_id": "448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com", - "client_type": 3 - } - ], - "api_key": [ - { - "current_key": "AIzaSyCuu4tbv9CwwTudNOweMNstzZHIDBhgJxA" - } - ], - "services": { - "appinvite_service": { - "other_platform_oauth_client": [ - { - "client_id": "448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com", - "client_type": 3 - }, - { - "client_id": "448618578101-54jhd806d0tr4vkgode0b4fi8iruvjpn.apps.googleusercontent.com", - "client_type": 2, - "ios_info": { - "bundle_id": "io.flutter.plugins.firebase.crashlytics.firebaseCrashlyticsExample" - } - } - ] - } - } - }, - { - "client_info": { - "mobilesdk_app_id": "1:448618578101:android:553625b1be8cf2efac3efc", - "android_client_info": { - "package_name": "io.flutter.plugins.firebasestorageexample" - } - }, - "oauth_client": [ - { - "client_id": "448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com", - "client_type": 3 - } - ], - "api_key": [ - { - "current_key": "AIzaSyCuu4tbv9CwwTudNOweMNstzZHIDBhgJxA" - } - ], - "services": { - "appinvite_service": { - "other_platform_oauth_client": [ - { - "client_id": "448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com", - "client_type": 3 - }, - { - "client_id": "448618578101-54jhd806d0tr4vkgode0b4fi8iruvjpn.apps.googleusercontent.com", - "client_type": 2, - "ios_info": { - "bundle_id": "io.flutter.plugins.firebase.crashlytics.firebaseCrashlyticsExample" - } - } - ] - } - } - }, - { - "client_info": { - "mobilesdk_app_id": "1:448618578101:android:b90da4e868ff1aafac3efc", - "android_client_info": { - "package_name": "org.reactjs.native.example.rnfbTestApplication" - } - }, - "oauth_client": [ - { - "client_id": "448618578101-fft7llalbhpetiiuqg4uk19jfp0tfefe.apps.googleusercontent.com", - "client_type": 1, - "android_info": { - "package_name": "org.reactjs.native.example.rnfbTestApplication", - "certificate_hash": "909ca1482ef022bbae45a2db6b6d05d807a4c4aa" - } - }, - { - "client_id": "448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com", + "client_id": "406099696497-a12gakvts4epfk5pkio7dphc1anjiggc.apps.googleusercontent.com", "client_type": 3 } ], "api_key": [ { - "current_key": "AIzaSyCuu4tbv9CwwTudNOweMNstzZHIDBhgJxA" + "current_key": "AIzaSyCdRjCVZlhrq72RuEklEyyxYlBRCYhI2Sw" } ], "services": { "appinvite_service": { "other_platform_oauth_client": [ { - "client_id": "448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com", + "client_id": "406099696497-a12gakvts4epfk5pkio7dphc1anjiggc.apps.googleusercontent.com", "client_type": 3 }, { - "client_id": "448618578101-54jhd806d0tr4vkgode0b4fi8iruvjpn.apps.googleusercontent.com", + "client_id": "406099696497-epk7902e2mb4pj4i4gcotk4q7dp2i9h3.apps.googleusercontent.com", "client_type": 2, "ios_info": { - "bundle_id": "io.flutter.plugins.firebase.crashlytics.firebaseCrashlyticsExample" + "bundle_id": "io.flutter.plugins.firebase.crashlytics.example" } } ] diff --git a/packages/firebase_crashlytics/firebase_crashlytics/example/android/build.gradle b/packages/firebase_crashlytics/firebase_crashlytics/example/android/build.gradle index 11e6ff0b69d5..e7032034e765 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics/example/android/build.gradle +++ b/packages/firebase_crashlytics/firebase_crashlytics/example/android/build.gradle @@ -6,8 +6,8 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:4.1.2' - classpath 'com.google.gms:google-services:4.3.4' - classpath 'com.google.firebase:firebase-crashlytics-gradle:2.2.0' + classpath 'com.google.gms:google-services:4.3.10' + classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1' } } diff --git a/packages/firebase_crashlytics/firebase_crashlytics/example/lib/firebase_options.dart b/packages/firebase_crashlytics/firebase_crashlytics/example/lib/firebase_options.dart new file mode 100644 index 000000000000..bf082e19b9bc --- /dev/null +++ b/packages/firebase_crashlytics/firebase_crashlytics/example/lib/firebase_options.dart @@ -0,0 +1,79 @@ +// File generated by FlutterFire CLI. +// ignore_for_file: lines_longer_than_80_chars +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.', + ); + } + // ignore: missing_enum_constant_in_switch + switch (defaultTargetPlatform) { + case TargetPlatform.android: + return android; + case TargetPlatform.iOS: + return ios; + case TargetPlatform.macOS: + return macos; + } + + throw UnsupportedError( + 'DefaultFirebaseOptions are not supported for this platform.', + ); + } + + static const FirebaseOptions android = FirebaseOptions( + apiKey: 'AIzaSyCdRjCVZlhrq72RuEklEyyxYlBRCYhI2Sw', + appId: '1:406099696497:android:0f3f7bfe78b8b7103574d0', + messagingSenderId: '406099696497', + projectId: 'flutterfire-e2e-tests', + databaseURL: + 'https://flutterfire-e2e-tests-default-rtdb.europe-west1.firebasedatabase.app', + storageBucket: 'flutterfire-e2e-tests.appspot.com', + ); + + static const FirebaseOptions ios = FirebaseOptions( + apiKey: 'AIzaSyDooSUGSf63Ghq02_iIhtnmwMDs4HlWS6c', + appId: '1:406099696497:ios:1d042a17c4dd64323574d0', + messagingSenderId: '406099696497', + projectId: 'flutterfire-e2e-tests', + databaseURL: + 'https://flutterfire-e2e-tests-default-rtdb.europe-west1.firebasedatabase.app', + storageBucket: 'flutterfire-e2e-tests.appspot.com', + androidClientId: + '406099696497-tvtvuiqogct1gs1s6lh114jeps7hpjm5.apps.googleusercontent.com', + iosClientId: + '406099696497-epk7902e2mb4pj4i4gcotk4q7dp2i9h3.apps.googleusercontent.com', + iosBundleId: 'io.flutter.plugins.firebase.crashlytics.example', + ); + + static const FirebaseOptions macos = FirebaseOptions( + apiKey: 'AIzaSyDooSUGSf63Ghq02_iIhtnmwMDs4HlWS6c', + appId: '1:406099696497:ios:1d042a17c4dd64323574d0', + messagingSenderId: '406099696497', + projectId: 'flutterfire-e2e-tests', + databaseURL: + 'https://flutterfire-e2e-tests-default-rtdb.europe-west1.firebasedatabase.app', + storageBucket: 'flutterfire-e2e-tests.appspot.com', + androidClientId: + '406099696497-tvtvuiqogct1gs1s6lh114jeps7hpjm5.apps.googleusercontent.com', + iosClientId: + '406099696497-epk7902e2mb4pj4i4gcotk4q7dp2i9h3.apps.googleusercontent.com', + iosBundleId: 'io.flutter.plugins.firebase.crashlytics.example', + ); +} diff --git a/packages/firebase_crashlytics/firebase_crashlytics/example/lib/main.dart b/packages/firebase_crashlytics/firebase_crashlytics/example/lib/main.dart index 0404fe2d3e5e..281be9d3357e 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics/example/lib/main.dart +++ b/packages/firebase_crashlytics/firebase_crashlytics/example/lib/main.dart @@ -11,6 +11,8 @@ import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'firebase_options.dart'; + // Toggle this to cause an async error to be thrown during initialization // and to test that runZonedGuarded() catches the error const _kShouldTestAsyncErrorOnInit = false; @@ -22,13 +24,7 @@ Future main() async { await runZonedGuarded(() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp( - options: const FirebaseOptions( - apiKey: 'AIzaSyAHAsf51D0A407EklG1bs-5wA7EbyfNFg0', - appId: '1:448618578101:ios:2bc5c1fe2ec336f8ac3efc', - messagingSenderId: '448618578101', - authDomain: 'react-native-firebase-testing.firebaseapp.com', - projectId: 'react-native-firebase-testing', - ), + options: DefaultFirebaseOptions.currentPlatform, ); FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError; runApp(MyApp()); @@ -55,8 +51,6 @@ class _MyAppState extends State { // Define an async function to initialize FlutterFire Future _initializeFlutterFire() async { - // Wait for Firebase to initialize - if (_kTestingCrashlytics) { // Force enable crashlytics collection enabled if we're testing it. await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true); @@ -106,7 +100,7 @@ class _MyAppState extends State { .showSnackBar(const SnackBar( content: Text( 'Custom Key "example: flutterfire" has been set \n' - 'Key will appear in Firebase Console once app has crashed and reopened'), + 'Key will appear in Firebase Console once an error has been reported.'), duration: Duration(seconds: 5), )); }, @@ -120,7 +114,7 @@ class _MyAppState extends State { .showSnackBar(const SnackBar( content: Text( 'The message "This is a log example" has been logged \n' - 'Message will appear in Firebase Console once app has crashed and reopened'), + 'Message will appear in Firebase Console once an error has been reported.'), duration: Duration(seconds: 5), )); }, @@ -148,8 +142,8 @@ class _MyAppState extends State { onPressed: () { ScaffoldMessenger.of(context) .showSnackBar(const SnackBar( - content: Text('Thrown error has been caught \n' - 'Please crash and reopen to send data to Crashlytics'), + content: Text( + 'Thrown error has been caught and sent to Crashlytics.'), duration: Duration(seconds: 5), )); @@ -164,8 +158,7 @@ class _MyAppState extends State { ScaffoldMessenger.of(context) .showSnackBar(const SnackBar( content: Text( - 'Uncaught Exception that is handled by second parameter of runZonedGuarded \n' - 'Please crash and reopen to send data to Crashlytics'), + 'Uncaught Exception that is handled by second parameter of runZonedGuarded.'), duration: Duration(seconds: 5), )); @@ -187,8 +180,7 @@ class _MyAppState extends State { try { ScaffoldMessenger.of(context) .showSnackBar(const SnackBar( - content: Text('Recorded Error \n' - 'Please crash and reopen to send data to Crashlytics'), + content: Text('Recorded Error'), duration: Duration(seconds: 5), )); throw Error(); @@ -207,8 +199,7 @@ class _MyAppState extends State { try { ScaffoldMessenger.of(context) .showSnackBar(const SnackBar( - content: Text('Recorded Error \n' - 'Please crash and reopen to send data to Crashlytics'), + content: Text('Recorded Error'), duration: Duration(seconds: 5), )); throw Error(); diff --git a/packages/firebase_crashlytics/firebase_crashlytics/example/macos/Runner.xcodeproj/project.pbxproj b/packages/firebase_crashlytics/firebase_crashlytics/example/macos/Runner.xcodeproj/project.pbxproj index e901845505be..1cf0a894d900 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics/example/macos/Runner.xcodeproj/project.pbxproj +++ b/packages/firebase_crashlytics/firebase_crashlytics/example/macos/Runner.xcodeproj/project.pbxproj @@ -26,12 +26,8 @@ 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; - 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; }; - 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; A778181074198B5AB83282EB /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D6342CA55BF53810F97AF20C /* Pods_Runner.framework */; }; B5515A0723F6830A00F4A798 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B5515A0623F6830A00F4A798 /* GoogleService-Info.plist */; }; - D73912F022F37F9E000D13A0 /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; }; - D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -51,8 +47,6 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */, - 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */, ); name = "Bundle Framework"; runOnlyForDeploymentPostprocessing = 0; @@ -71,7 +65,6 @@ 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; - 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FlutterMacOS.framework; path = Flutter/ephemeral/FlutterMacOS.framework; sourceTree = SOURCE_ROOT; }; 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; @@ -81,7 +74,6 @@ AD1C0B47B3CC4549F903FB8C /* 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 = ""; }; B5515A0623F6830A00F4A798 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; D6342CA55BF53810F97AF20C /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - D73912EF22F37F9E000D13A0 /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/ephemeral/App.framework; sourceTree = SOURCE_ROOT; }; F66FF69A43A7D1A9235BA2DA /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -90,8 +82,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - D73912F022F37F9E000D13A0 /* App.framework in Frameworks */, - 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */, A778181074198B5AB83282EB /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -158,8 +148,6 @@ 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, - D73912EF22F37F9E000D13A0 /* App.framework */, - 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */, ); path = Flutter; sourceTree = ""; @@ -285,7 +273,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename\n"; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; }; 33CC111E2044C6BF0003C045 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; @@ -334,10 +322,27 @@ buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/FirebaseCore/FirebaseCore.framework", + "${BUILT_PRODUCTS_DIR}/FirebaseCoreDiagnostics/FirebaseCoreDiagnostics.framework", + "${BUILT_PRODUCTS_DIR}/FirebaseCrashlytics/FirebaseCrashlytics.framework", + "${BUILT_PRODUCTS_DIR}/FirebaseInstallations/FirebaseInstallations.framework", + "${BUILT_PRODUCTS_DIR}/GoogleDataTransport/GoogleDataTransport.framework", + "${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework", + "${BUILT_PRODUCTS_DIR}/PromisesObjC/FBLPromises.framework", + "${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework", ); name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCore.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCoreDiagnostics.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCrashlytics.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseInstallations.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleDataTransport.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleUtilities.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FBLPromises.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nanopb.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; diff --git a/packages/firebase_crashlytics/firebase_crashlytics/example/macos/Runner/GoogleService-Info.plist b/packages/firebase_crashlytics/firebase_crashlytics/example/macos/Runner/GoogleService-Info.plist index c9c6c3ae12aa..e6c9fe545762 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics/example/macos/Runner/GoogleService-Info.plist +++ b/packages/firebase_crashlytics/firebase_crashlytics/example/macos/Runner/GoogleService-Info.plist @@ -2,39 +2,37 @@ - AD_UNIT_ID_FOR_BANNER_TEST - ca-app-pub-3940256099942544/2934735716 - AD_UNIT_ID_FOR_INTERSTITIAL_TEST - ca-app-pub-3940256099942544/4411468910 CLIENT_ID - 380450695418-j9bquuvdhv7iimnca4n7mhrp9a0kv9un.apps.googleusercontent.com + 406099696497-epk7902e2mb4pj4i4gcotk4q7dp2i9h3.apps.googleusercontent.com REVERSED_CLIENT_ID - com.googleusercontent.apps.380450695418-j9bquuvdhv7iimnca4n7mhrp9a0kv9un + com.googleusercontent.apps.406099696497-epk7902e2mb4pj4i4gcotk4q7dp2i9h3 + ANDROID_CLIENT_ID + 406099696497-tvtvuiqogct1gs1s6lh114jeps7hpjm5.apps.googleusercontent.com API_KEY - AIzaSyDKzrI_W_MaUt46jthsPB7FTG-RdSKeKEw + AIzaSyDooSUGSf63Ghq02_iIhtnmwMDs4HlWS6c GCM_SENDER_ID - 380450695418 + 406099696497 PLIST_VERSION 1 BUNDLE_ID - io.flutter.plugins.firebase.crashlytics.firebaseCrashlyticsExample + io.flutter.plugins.firebase.crashlytics.example PROJECT_ID - firebase-for-flutter-xry + flutterfire-e2e-tests STORAGE_BUCKET - firebase-for-flutter-xry.appspot.com + flutterfire-e2e-tests.appspot.com IS_ADS_ENABLED - + IS_ANALYTICS_ENABLED IS_APPINVITE_ENABLED - + IS_GCM_ENABLED IS_SIGNIN_ENABLED GOOGLE_APP_ID - 1:380450695418:ios:2693ad5ab6a23cde + 1:406099696497:ios:1d042a17c4dd64323574d0 DATABASE_URL - https://fir-for-flutter-xry.firebaseio.com + https://flutterfire-e2e-tests-default-rtdb.europe-west1.firebasedatabase.app \ No newline at end of file diff --git a/packages/firebase_crashlytics/firebase_crashlytics/ios/Classes/Crashlytics_Platform.h b/packages/firebase_crashlytics/firebase_crashlytics/ios/Classes/Crashlytics_Platform.h index 017b11cf4049..d28a16534fc9 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics/ios/Classes/Crashlytics_Platform.h +++ b/packages/firebase_crashlytics/firebase_crashlytics/ios/Classes/Crashlytics_Platform.h @@ -25,6 +25,8 @@ @property(nonatomic, strong, nullable) NSString* developmentPlatformName; @property(nonatomic, strong, nullable) NSString* developmentPlatformVersion; +- (void)recordOnDemandExceptionModel:(FIRExceptionModel* _Nonnull)exceptionModel; + @end void FIRCLSUserLoggingRecordInternalKeyValue(NSString* _Nullable key, id _Nullable value); diff --git a/packages/firebase_crashlytics/firebase_crashlytics/ios/Classes/ExceptionModel_Platform.h b/packages/firebase_crashlytics/firebase_crashlytics/ios/Classes/ExceptionModel_Platform.h new file mode 100644 index 000000000000..3f380cf3602d --- /dev/null +++ b/packages/firebase_crashlytics/firebase_crashlytics/ios/Classes/ExceptionModel_Platform.h @@ -0,0 +1,28 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// Crashlytics_ExceptionModel.h +// Crashlytics +// + +#import + +@interface FIRExceptionModel (Platform) + +@property(nonatomic) BOOL isFatal; +@property(nonatomic) BOOL onDemand; + +@end diff --git a/packages/firebase_crashlytics/firebase_crashlytics/ios/Classes/FLTFirebaseCrashlyticsPlugin.m b/packages/firebase_crashlytics/firebase_crashlytics/ios/Classes/FLTFirebaseCrashlyticsPlugin.m index a398e7ceb204..856e52222d69 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics/ios/Classes/FLTFirebaseCrashlyticsPlugin.m +++ b/packages/firebase_crashlytics/firebase_crashlytics/ios/Classes/FLTFirebaseCrashlyticsPlugin.m @@ -4,6 +4,7 @@ #import "FLTFirebaseCrashlyticsPlugin.h" #import "Crashlytics_Platform.h" +#import "ExceptionModel_Platform.h" #import @@ -160,12 +161,6 @@ - (void)recordError:(id)arguments withMethodCallResult:(FLTFirebaseMethodCallRes NSTimeInterval timeInterval = [NSDate date].timeIntervalSince1970; [[FIRCrashlytics crashlytics] setCustomValue:@(llrint(timeInterval)) forKey:@"com.firebase.crashlytics.flutter.fatal"]; -#if TARGET_OS_OSX - // macOS platform does not support analytics -#else - id analytics = [[FIRCrashlytics crashlytics].analyticsManager analytics]; - [FIRCLSAnalyticsManager logCrashWithTimeStamp:timeInterval toAnalytics:analytics]; -#endif } // Log additional custom value to match Android. @@ -176,7 +171,13 @@ - (void)recordError:(id)arguments withMethodCallResult:(FLTFirebaseMethodCallRes reason:reason]; exception.stackTrace = frames; - [[FIRCrashlytics crashlytics] recordExceptionModel:exception]; + exception.onDemand = YES; + exception.isFatal = fatal; + if (fatal) { + [[FIRCrashlytics crashlytics] recordOnDemandExceptionModel:exception]; + } else { + [[FIRCrashlytics crashlytics] recordExceptionModel:exception]; + } result.success(nil); } diff --git a/packages/firebase_crashlytics/firebase_crashlytics/lib/src/firebase_crashlytics.dart b/packages/firebase_crashlytics/firebase_crashlytics/lib/src/firebase_crashlytics.dart index f23436b13fa0..7fb114f2fe5e 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics/lib/src/firebase_crashlytics.dart +++ b/packages/firebase_crashlytics/firebase_crashlytics/lib/src/firebase_crashlytics.dart @@ -129,8 +129,10 @@ class FirebaseCrashlytics extends FirebasePluginPlatform { ); } - /// Submits a Crashlytics report of a non-fatal error caught by the Flutter framework. - Future recordFlutterError(FlutterErrorDetails flutterErrorDetails) { + /// Submits a Crashlytics report of an error caught by the Flutter framework. + /// Use [fatal] to indicate whether the error is a fatal or not. + Future recordFlutterError(FlutterErrorDetails flutterErrorDetails, + {bool fatal = false}) { FlutterError.presentError(flutterErrorDetails); return recordError( @@ -141,6 +143,7 @@ class FirebaseCrashlytics extends FirebasePluginPlatform { ? [] : flutterErrorDetails.informationCollector!(), printDetails: false, + fatal: fatal, ); } From f2df83cde8ae1762dbf37491602532fe8b3e0f8f Mon Sep 17 00:00:00 2001 From: Mike Diarmid Date: Fri, 29 Apr 2022 11:31:52 +0100 Subject: [PATCH 2/4] chore(release): prepare for release (#8543) --- CHANGELOG.md | 21 +++++++++++++++++++ .../firebase_crashlytics/CHANGELOG.md | 4 ++++ .../firebase_crashlytics/pubspec.yaml | 2 +- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dbb44d55c29d..1ac2acab59b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,27 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## 2022-04-29 + +### Changes + +--- + +Packages with breaking changes: + + - There are no breaking changes in this release. + +Packages with other changes: + + - [`firebase_crashlytics` - `v2.7.0`](#firebase_crashlytics---v270) + +--- + +#### `firebase_crashlytics` - `v2.7.0` + + - **FEAT**: add support for on-demand exception reporting (#8540). ([dfec7d60](https://github.com/FirebaseExtended/flutterfire/commit/dfec7d60592abe0a5c6523e13feabffb8b03020b)) + + ## 2022-04-27 ### Changes diff --git a/packages/firebase_crashlytics/firebase_crashlytics/CHANGELOG.md b/packages/firebase_crashlytics/firebase_crashlytics/CHANGELOG.md index a7888c946577..49d075c8396d 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics/CHANGELOG.md +++ b/packages/firebase_crashlytics/firebase_crashlytics/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.7.0 + + - **FEAT**: add support for on-demand exception reporting (#8540). ([dfec7d60](https://github.com/FirebaseExtended/flutterfire/commit/dfec7d60592abe0a5c6523e13feabffb8b03020b)) + ## 2.6.3 - Update a dependency to the latest release. diff --git a/packages/firebase_crashlytics/firebase_crashlytics/pubspec.yaml b/packages/firebase_crashlytics/firebase_crashlytics/pubspec.yaml index 269ba1824d3e..8d71871694a4 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics/pubspec.yaml +++ b/packages/firebase_crashlytics/firebase_crashlytics/pubspec.yaml @@ -2,7 +2,7 @@ name: firebase_crashlytics description: Flutter plugin for Firebase Crashlytics. It reports uncaught errors to the Firebase console. -version: 2.6.3 +version: 2.7.0 homepage: https://firebase.flutter.dev/docs/crashlytics/overview repository: https://github.com/FirebaseExtended/flutterfire/tree/master/packages/firebase_crashlytics/firebase_crashlytics From 8ef8b55c113f24abac783170723c7f784f5d1fe5 Mon Sep 17 00:00:00 2001 From: Mike Diarmid Date: Fri, 29 Apr 2022 18:00:38 +0100 Subject: [PATCH 3/4] fix(crashlytics): re-add support for `recordFlutterFatalError` method from previous EAP API (#8550) --- .../firebase_crashlytics/lib/src/firebase_crashlytics.dart | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/firebase_crashlytics/firebase_crashlytics/lib/src/firebase_crashlytics.dart b/packages/firebase_crashlytics/firebase_crashlytics/lib/src/firebase_crashlytics.dart index 7fb114f2fe5e..593afbaac8dd 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics/lib/src/firebase_crashlytics.dart +++ b/packages/firebase_crashlytics/firebase_crashlytics/lib/src/firebase_crashlytics.dart @@ -147,6 +147,12 @@ class FirebaseCrashlytics extends FirebasePluginPlatform { ); } + /// Submits a Crashlytics report of a fatal error caught by the Flutter framework. + Future recordFlutterFatalError( + FlutterErrorDetails flutterErrorDetails) { + return recordFlutterError(flutterErrorDetails, fatal: true); + } + /// Logs a message that's included in the next fatal or non-fatal report. /// /// Logs are visible in the session view on the Firebase Crashlytics console. From 7e3048f5ce6d2d04c50e4db16ce246452bcf4918 Mon Sep 17 00:00:00 2001 From: Mike Diarmid Date: Tue, 3 May 2022 09:17:06 +0100 Subject: [PATCH 4/4] chore(release): prepare for release (#8551) --- CHANGELOG.md | 21 +++++++++++++++++++ .../firebase_crashlytics/CHANGELOG.md | 4 ++++ .../firebase_crashlytics/pubspec.yaml | 2 +- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ac2acab59b0..d996acfcb575 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,27 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## 2022-04-29 + +### Changes + +--- + +Packages with breaking changes: + + - There are no breaking changes in this release. + +Packages with other changes: + + - [`firebase_crashlytics` - `v2.7.1`](#firebase_crashlytics---v271) + +--- + +#### `firebase_crashlytics` - `v2.7.1` + + - **FIX**: re-add support for `recordFlutterFatalError` method from previous EAP API (#8550). ([8ef8b55c](https://github.com/FirebaseExtended/flutterfire/commit/8ef8b55c113f24abac783170723c7f784f5d1fe5)) + + ## 2022-04-29 ### Changes diff --git a/packages/firebase_crashlytics/firebase_crashlytics/CHANGELOG.md b/packages/firebase_crashlytics/firebase_crashlytics/CHANGELOG.md index 49d075c8396d..4e6f72d964a4 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics/CHANGELOG.md +++ b/packages/firebase_crashlytics/firebase_crashlytics/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.7.1 + + - **FIX**: re-add support for `recordFlutterFatalError` method from previous EAP API (#8550). ([8ef8b55c](https://github.com/FirebaseExtended/flutterfire/commit/8ef8b55c113f24abac783170723c7f784f5d1fe5)) + ## 2.7.0 - **FEAT**: add support for on-demand exception reporting (#8540). ([dfec7d60](https://github.com/FirebaseExtended/flutterfire/commit/dfec7d60592abe0a5c6523e13feabffb8b03020b)) diff --git a/packages/firebase_crashlytics/firebase_crashlytics/pubspec.yaml b/packages/firebase_crashlytics/firebase_crashlytics/pubspec.yaml index 8d71871694a4..6cc99c0cb154 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics/pubspec.yaml +++ b/packages/firebase_crashlytics/firebase_crashlytics/pubspec.yaml @@ -2,7 +2,7 @@ name: firebase_crashlytics description: Flutter plugin for Firebase Crashlytics. It reports uncaught errors to the Firebase console. -version: 2.7.0 +version: 2.7.1 homepage: https://firebase.flutter.dev/docs/crashlytics/overview repository: https://github.com/FirebaseExtended/flutterfire/tree/master/packages/firebase_crashlytics/firebase_crashlytics