diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 834937392..c16abb508 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -11,25 +11,30 @@ assignees: '' IMPORTANT: PLEASE READ WARNING: Failure to follow the issue template guidelines below will result in the issue being immediately closed. - -Only bug reports should be opened here. - -Before opening an issue, please do the following: -- check a similar issue is not already open (or closed) against this plugin. - - Duplicates or near-duplicates will be closed immediately. -- try to reproduce the issue using the example project - - or if that's not possible, using an isolated test project that you are able to share - - this will eliminate bugs in your code or conflicts with other code as possible causes of the issue -- any issue which is suspected of being caused by the Ionic Native wrapper should be [reported against Ionic Native](https://github.com/ionic-team/ionic-native/issues/new) - - Ionic Native Typescript wrappers are maintained by the Ionic Team - - To verify an if an issue is caused by this plugin or its Typescript wrapper, please re-test using the vanilla Javascript plugin interface (without the Ionic Native wrapper). - - Any issue opened here which is obviously an Ionic Typescript wrapper issue will be closed immediately. --> # Bug report + +**CHECKLIST** +- [ ] I have read the [issue reporting guidelines](https://github.com/dpa99c/cordova-plugin-firebasex#reporting-issues) + +- [ ] I confirm this is a suspected bug or issue that will affect other users + + +- [ ] I have reproduced the issue using the [example project](https://github.com/dpa99c/cordova-plugin-firebasex-test) or provided the necessary information to reproduce the issue. + + +- [ ] I have read [the documentation](https://github.com/dpa99c/cordova-plugin-firebasex) thoroughly and it does not help solve my issue. + + +- [ ] I have checked that no similar issues (open or closed) already exist. + + + + **Current behavior:** @@ -117,4 +122,4 @@ A POLITE REMINDER - Help/support will not be given by the author, so forums (e.g. Ionic) or Stack Overflow should be used. Any issues requesting help/support will be closed immediately. - If you have urgent need of a bug fix/feature, the author can be engaged for PAID contract work to do so: please contact dave@workingedge.co.uk - Rude or abusive comments/issues will not be tolerated, nor will opening multiple issues if those previously closed are deemed unsuitable. Any of the above will result in you being BANNED from ALL of my Github repositories. ---> \ No newline at end of file +--> diff --git a/.github/ISSUE_TEMPLATE/documentation-issue.md b/.github/ISSUE_TEMPLATE/documentation-issue.md index dcbcee646..f8d8d8196 100644 --- a/.github/ISSUE_TEMPLATE/documentation-issue.md +++ b/.github/ISSUE_TEMPLATE/documentation-issue.md @@ -11,7 +11,7 @@ WARNING: Failure to follow the issue template guidelines below will result in th Only documentation issues should be opened here. -Before opening an issue, please check a similar issue is not already open (or closed). Duplicates or near-duplicates will be closed immediately. +Before opening an issue, please read [Reporting issues](https://github.com/dpa99c/cordova-plugin-firebasex#reporting-issues) --> @@ -33,4 +33,4 @@ A POLITE REMINDER - Help/support will not be given by the author, so forums (e.g. Ionic) or Stack Overflow should be used. Any issues requesting help/support will be closed immediately. - If you have urgent need of a bug fix/feature, the author can be engaged for PAID contract work to do so: please contact dave@workingedge.co.uk - Rude or abusive comments/issues will not be tolerated, nor will opening multiple issues if those previously closed are deemed unsuitable. Any of the above will result in you being BANNED from ALL of my Github repositories. ---> \ No newline at end of file +--> diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 559f6517f..539d77663 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -11,6 +11,8 @@ WARNING: Failure to follow the issue template guidelines below will result in th Only feature requests should be opened here. +Before opening an issue, please read [Reporting issues](https://github.com/dpa99c/cordova-plugin-firebasex#reporting-issues) + --> @@ -38,4 +40,4 @@ A POLITE REMINDER - Help/support will not be given by the author, so forums (e.g. Ionic) or Stack Overflow should be used. Any issues requesting help/support will be closed immediately. - If you have urgent need of a bug fix/feature, the author can be engaged for PAID contract work to do so: please contact dave@workingedge.co.uk - Rude or abusive comments/issues will not be tolerated, nor will opening multiple issues if those previously closed are deemed unsuitable. Any of the above will result in you being BANNED from ALL of my Github repositories. ---> \ No newline at end of file +--> diff --git a/CHANGELOG.md b/CHANGELOG.md index 079b6b52a..034a5491f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,31 @@ -# Version 9.1.0 +# Version 9.1.2-cli +* (Android) Fix retrieval of auth provider ID - [see here for more info](https://github.com/firebase/FirebaseUI-Android/issues/329#issuecomment-564409912) +* (iOS) Align retrieval of auth provider ID with Android. +* (Typing): correct return type of a method + * Merged from PR [#390](https://github.com/dpa99c/cordova-plugin-firebasex/pull/390). +* (Documentation) Update guidance and requirements when opening issues +* (iOS): Fix escaping of line endings in multi-line log messages being sent from native iOS implementation to JS console. + * Resolves [#401](https://github.com/dpa99c/cordova-plugin-firebasex/issues/401). +* (iOS): Set shouldEstablishDirectChannel via a plugin variable which defaults to false. + Resolves [#406](https://github.com/dpa99c/cordova-plugin-firebasex/issues/406). +* Bump androidx plugin version dependencies. + Resolves [#418](https://github.com/dpa99c/cordova-plugin-firebasex/issues/418). + +# Version 9.1.1-cli +* (iOS): Bump Firebase SDK components to v6.23.0. + * Relates to [#373](https://github.com/dpa99c/cordova-plugin-firebasex/issues/373). + * See https://firebase.google.com/support/release-notes/ios#version_6230_-_april_21_2020. +* (Android) Bump Firebase SDK (and other Gradle dependencies) to latest versions. + * See https://firebase.google.com/support/release-notes/android#2020-04-23 + +# Version 9.1.0-cli * (Android & iOS) *BREAKING CHANGE*: Add support for filters to `fetchDocumentInFirestoreCollection()` * *BREAKING CHANGE* to function signature. * Merged from PR [#367](https://github.com/dpa99c/cordova-plugin-firebasex/pull/367). +* (Android) Fix regression bug which causes CLI builds to fail on Android. +Resolves [#369](https://github.com/dpa99c/cordova-plugin-firebasex/issues/369). -# Version 9.0.3 +# Version 9.0.3-cli * (Android & iOS) Add `reloadCurrentUser()` * (Doc) `createChannel()` suggestion for multiple sounds * Merged from PR [#225](https://github.com/dpa99c/cordova-plugin-firebasex/pull/225). @@ -11,15 +33,17 @@ * Merged from PR [#363](https://github.com/dpa99c/cordova-plugin-firebasex/pull/363). * (Android & iOS) Add `signInUserWithCustomToken()` AND `signInUserAnonymously()` auth methods * Merged from PR [#359](https://github.com/dpa99c/cordova-plugin-firebasex/pull/359). + +# Version 9.0.2-cli -# Version 9.0.2 * (Android): Don't display app icon for large notification icon on Android. Resolves [#343](https://github.com/dpa99c/cordova-plugin-firebasex/issues/343). * (Android & iOS) Sign out of Google signing out of Firebase. Resolves [#353](https://github.com/dpa99c/cordova-plugin-firebasex/issues/353). * (Android & iOS) Add `documentExistsInFirestoreCollection()` and fix resolution of `fetchDocumentInFirestoreCollection()`. -# Version 9.0.1 -* Re-add Firebase Inapp Messaging SDK component to master branch. -* Document `cli_build` branch. See [#326](https://github.com/dpa99c/cordova-plugin-firebasex/issues/326). +# Version 9.0.1-cli +* Document `cli_build` branch. +* *BREAKING CHANGE*: Remove Firebase Inapp Messaging and Google Tag Manager SDK components due to causing Cordova CLI build issues. + * Resolves [#326](https://github.com/dpa99c/cordova-plugin-firebasex/issues/326). # Version 9.0.0 * *BREAKING CHANGE*: Change method signature of `setCrashlyticsCollectionEnabled()` to `(enabled, success, error)` (from `()`) to allow enabling/disabling of Crashlytics at runtime and align it with `setPerformanceCollectionEnabled()` and `setAnalyticsCollectionEnabled()` diff --git a/README.md b/README.md index 9760ee520..a652ce9f2 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,26 @@ cordova-plugin-firebasex [![Latest Stable Version](https://img.shields.io/npm/v/ Brings push notifications, analytics, event tracking, crash reporting and more from Google Firebase to your Cordova project. +Upgraded to the Firebase Crahlytics SDK for both [Android](https://firebase.google.com/docs/crashlytics/upgrade-sdk?platform=android) & [iOS](https://firebase.google.com/docs/crashlytics/upgrade-sdk?platform=ios) + Supported platforms: Android and iOS +**IMPORTANT:** Before opening an issue against this plugin, please read [Reporting issues](#reporting-issues). + +# cli_build branch +This branch of the plugin is specifically intended for those building (directly or indirectly) via the Cordova CLI. +It removes the Firebase Inapp Messaging and Google Tag Manager SDK components due to these causing CLI builds to fail (see [#326](https://github.com/dpa99c/cordova-plugin-firebasex/issues/326)). + +To use it, install an npm release with the `-cli` suffix, e.g.: + + cordova plugin add cordova-plugin-firebasex@9.1.2-cli + +Or install it directly from this branch: + + cordova plugin add https://github.com/dpa99c/cordova-plugin-firebasex#cli_build + +If you wish to use either of these components, please use the [master](https://github.com/dpa99c/cordova-plugin-firebasex) branch or install a major plugin release via the NPM registry and build using Xcode. + [![donate](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG_global.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=ZRD3W47HQ3EMJ) @@ -44,6 +62,8 @@ To help ensure this plugin is kept updated, new features are added and bugfixes - [Disable data collection on startup](#disable-data-collection-on-startup) - [Example project](#example-project) - [Reporting issues](#reporting-issues) + - [Reporting a bug or problem](#reporting-a-bug-or-problem) + - [Requesting a new feature](#requesting-a-new-feature) - [Cloud messaging](#cloud-messaging) - [Background notifications](#background-notifications) - [Foreground notifications](#foreground-notifications) @@ -196,7 +216,6 @@ The following plugin variables are used to specify the Firebase SDK versions as - `ANDROID_FIREBASE_CONFIG_VERSION` - `ANDROID_FIREBASE_PERF_VERSION` - `ANDROID_FIREBASE_AUTH_VERSION` -- `$ANDROID_FIREBASE_INAPPMESSAGING_VERSION` - `ANDROID_FIREBASE_FIRESTORE_VERSION` - `ANDROID_CRASHLYTICS_VERSION` - `ANDROID_CRASHLYTICS_NDK_VERSION` @@ -207,7 +226,16 @@ See [Specifying Android library versions](#specifying-android-library-versions) ### iOS only - `IOS_STRIP_DEBUG` - prevents symbolification of all libraries included via Cocoapods. See [Strip debug symbols](#strip-debug-symbols) for more info. -- `SETUP_RECAPTCHA_VERIFICATION` - automatically sets up reCAPTCHA verification for phone authentication on iOS. See [verifyPhoneNumber](#verifyphonenumber) for more info. + - e.g. `--variable IOS_STRIP_DEBUG=true` + - Defaults to `false` if not specified. +- `SETUP_RECAPTCHA_VERIFICATION` - automatically sets up reCAPTCHA verification for phone authentication on iOS. See [verifyPhoneNumber](#verifyphonenumber) for more info. + - e.g. `--variable IOS_STRIP_DEBUG=true` + - Defaults to `false` if not specified. +- `IOS_SHOULD_ESTABLISH_DIRECT_CHANNEL` - If `true` Firebase Messaging will automatically establish a socket-based, direct channel to the FCM server. + - e.g. `--variable IOS_SHOULD_ESTABLISH_DIRECT_CHANNEL=true` + - Defaults to `false` if not specified. + - See [`shouldEstablishDirectChannel`](https://firebase.google.com/docs/reference/ios/firebasemessaging/api/reference/Classes/FIRMessaging#/c:objc(cs)FIRMessaging(py)shouldEstablishDirectChannel) + - Note: Firebase Messaging iOS SDK version 7.0 will be a breaking change where the SDK will no longer support iOS Direct Channel API. ## Supported Cordova Versions - cordova: `>= 9` @@ -361,7 +389,6 @@ The following plugin variables are used to specify the following Gradle dependen - `ANDROID_FIREBASE_PERF_VERSION` => `com.google.firebase:firebase-perf` - `ANDROID_FIREBASE_AUTH_VERSION` => `com.google.firebase:firebase-auth` - `ANDROID_FIREBASE_FIRESTORE_VERSION` => `com.google.firebase:firebase-firestore` -- `$ANDROID_FIREBASE_INAPPMESSAGING_VERSION` => `com.google.firebase:firebase-inappmessaging-display` - `ANDROID_CRASHLYTICS_VERSION` => `com.crashlytics.sdk.android:crashlytics` - `ANDROID_CRASHLYTICS_NDK_VERSION` => `com.crashlytics.sdk.android:crashlytics-ndk` - `ANDROID_GSON_VERSION` => `com.google.code.gson:gson` @@ -501,16 +528,54 @@ Please use this as a working reference. Before reporting any issues, please (if possible) test against the example project to rule out causes external to this plugin. # Reporting issues -Before reporting an issue with this plugin, please do the following: -- check a similar issue is not already open (or closed) against this plugin. -- try to reproduce the issue using the example project - - or if that's not possible, using an isolated test project that you are able to share - - this will eliminate bugs in your code or conflicts with other code as possible causes of the issue -- any issue which is suspected of being caused by the Ionic Native wrapper should be [reported against Ionic Native](https://github.com/ionic-team/ionic-native/issues/new) - - Ionic Native Typescript wrappers are maintained by the Ionic Team +**IMPORTANT:** Please read the following carefully. +Failure to follow the issue template guidelines below will result in the issue being immediately closed. + +## Reporting a bug or problem +Before [opening a bug issue](https://github.com/dpa99c/cordova-plugin-firebasex/issues/new?assignees=&labels=&template=bug_report.md&title=), please do the following: +- *DO NOT* open issues asking for support in using/integrating the plugin into your project + - Only open issues for suspected bugs/issues with the plugin that are generic and will affect other users + - I don't have time to offer free technical support: this is free open-source software + - Ask for help on StackOverflow, Ionic Forums, etc. + - Use the [example project](https://github.com/dpa99c/cordova-plugin-firebasex-test) as a known working reference + - Any issues requesting support will be closed immediately. +- *DO NOT* open issues related to the [Ionic Typescript wrapper for this plugin](https://github.com/ionic-team/ionic-native/blob/master/src/%40ionic-native/plugins/firebase-x/index.ts) + - This is owned/maintained by [Ionic](https://github.com/ionic-team) and is not part of this plugin + - Please raise such issues/PRs against [Ionic Native](https://github.com/ionic-team/ionic-native/) instead. - To verify an if an issue is caused by this plugin or its Typescript wrapper, please re-test using the vanilla Javascript plugin interface (without the Ionic Native wrapper). -- if you are having build problems, ensure you have thoroughly read the [Build environment notes](#build-environment-notes) section and searched existing open/closed issues for a similar problem. -- if you are migrating from `cordova-plugin-firebase` to `cordova-plugin-firebasex` please make sure you have read the [Migrating from cordova-plugin-firebase](#migrating-from-cordova-plugin-firebase) section. + - Any issue opened here which is obviously an Ionic Typescript wrapper issue will be closed immediately. +- If you are migrating from [cordova-plugin-firebase](https://github.com/arnesson/cordova-plugin-firebase) to `cordova-plugin-firebasex` please make sure you have read the [Migrating from cordova-plugin-firebase](#migrating-from-cordova-plugin-firebase) section. +- Read the above documentation thoroughly + - For example, if you're having a build issue ensure you've read through the [build environment notes](#build-environment-notes) + - If an iOS CLI build is failing, ensure you've read the [Cordova CLI builds](#cordova-cli-builds) section +- Check the [CHANGELOG](https://github.com/dpa99c/cordova-plugin-firebasex/blob/master/CHANGELOG.md) for any breaking changes that may be causing your issue. +- Check a similar issue (open or closed) does not already exist against this plugin. + - Duplicates or near-duplicates will be closed immediately. +- When [creating a new issue](https://github.com/dpa99c/cordova-plugin-firebasex/issues/new/choose) + - Choose the "Bug report" template + - Fill out the relevant sections of the template and delete irrelevant sections + - *WARNING:* Failure to complete the issue template will result in the issue being closed immediately. +- Reproduce the issue using the [example project](https://github.com/dpa99c/cordova-plugin-firebasex-test) + - This will eliminate bugs in your code or conflicts with other code as possible causes of the issue + - This will also validate your development environment using a known working codebase + - If reproducing the issue using the example project is not possible, create an isolated test project that you are able to share +- Include full verbose console output when reporting build issues + - If the full console output is too large to insert directly into the Github issue, then post it on an external site such as [Pastebin](https://pastebin.com/) and link to it from the issue + - Often the details of an error causing a build failure is hidden away when building with the CLI + - To get the full detailed console output, append the `--verbose` flag to CLI build commands + - e.g. `cordova build ios --verbose` + - Failure to include the full console output will result in the issue being closed immediately +- If the issue relates to the plugin documentation (and not the code), please of a [documentation issue](https://github.com/dpa99c/cordova-plugin-firebasex/issues/new?assignees=&labels=&template=documentation-issue.md&title=) + +## Requesting a new feature +Before [opening a feature request issue](https://github.com/dpa99c/cordova-plugin-firebasex/issues/new?assignees=&labels=&template=feature_request.md&title=), please do the following: +- Check the above documentation to ensure the feature you are requesting doesn't already exist +- Check the list if open/closed issues to check if there's a reason that feature hasn't been included already +- Ensure the feature you are requesting is actually possible to implement and generically useful to other users than yourself +- Where possible, post a link to the documentation related to the feature you are requesting +- Include other relevant links, e.g. + - Stack Overflow post illustrating a solution + - Code within another Github repo that illustrates a solution # Cloud messaging @@ -1176,27 +1241,12 @@ The [example project](https://github.com/dpa99c/cordova-plugin-firebasex-test) c You can test this by building and running the example project app, and sending the [notification_custom_receiver](https://github.com/dpa99c/cordova-plugin-firebasex-test/blob/master/messages/notification_custom_receiver.json) and [data_custom_receiver](https://github.com/dpa99c/cordova-plugin-firebasex-test/blob/master/messages/data_custom_receiver.json) test messages using the [built-in FCM client](https://github.com/dpa99c/cordova-plugin-firebasex-test#messaging-client). # InApp Messaging -Engage active app users with contextual messages. -The SDK component is included in the plugin but no explicit plugin API calls are required to use inapp messaging. - -See the [iOS](https://firebase.google.com/docs/in-app-messaging/get-started?platform=ios#send_a_test_message) and [Android](https://firebase.google.com/docs/in-app-messaging/get-started?platform=android#send_a_test_message) guides for how to send a test message. +The Firebase Inapp Messaging SDK component has been removed from this [cli_build](https://github.com/dpa99c/cordova-plugin-firebasex/tree/cli_build) branch of the plugin due to the iOS component causing CLI builds to fail (see [#326](https://github.com/dpa99c/cordova-plugin-firebasex/issues/326)). +If you wish to use Firebase Inapp Messaging, please use the [master](https://github.com/dpa99c/cordova-plugin-firebasex) branch or install a plugin release via the NPM registry and build using Xcode. # Google Tag Manager -Download your container-config json file from Tag Manager and add a `` node in your `config.xml`. - -## Android -```xml - - - ... -``` - -## iOS -```xml - - - ... -``` +The Google Tag Manager component has been removed from this [cli_build](https://github.com/dpa99c/cordova-plugin-firebasex/tree/cli_build) branch of the plugin due to the iOS component causing CLI builds to fail (see [#326](https://github.com/dpa99c/cordova-plugin-firebasex/issues/326)). +If you wish to use Google Tag Manager, please use the [master](https://github.com/dpa99c/cordova-plugin-firebasex) branch or install a plugin release via the NPM registry and build using Xcode. # API The list of available methods for this plugin is described below. @@ -2881,8 +2931,6 @@ FirebasePlugin.fetchFirestoreCollection(collection, filters, function(documents) }); ``` - - # Credits - [@robertarnesson](https://github.com/robertarnesson) for the original [cordova-plugin-firebase](https://github.com/arnesson/cordova-plugin-firebase) from which this plugin is forked. - [@sagrawal31](https://github.com/sagrawal31) and [Wiz Panda](https://github.com/wizpanda) for contributions via [cordova-plugin-firebase-lib](https://github.com/wizpanda/cordova-plugin-firebase-lib). diff --git a/package.json b/package.json index f06f88669..37e0f1e16 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cordova-plugin-firebasex", - "version": "9.1.0", + "version": "9.1.2-cli", "description": "Cordova plugin for Google Firebase", "types": "./types/index.d.ts", "author": { @@ -36,7 +36,7 @@ }, "dependencies": { "plist": "^3.0.1", - "xcode": "^2.0.0", + "xcode": "^3.0.1", "xml-js": "^1.6.11" } } diff --git a/plugin.xml b/plugin.xml index 9706a43c4..e6697510a 100644 --- a/plugin.xml +++ b/plugin.xml @@ -1,13 +1,13 @@ - Google Firebase Plugin MIT - - + + @@ -61,30 +61,26 @@ - - - - - - - - - - - + + + + + + + + + - - - - + + @@ -131,17 +127,14 @@ - - - - - - - - - + + + + + + + - diff --git a/scripts/ios/helper.js b/scripts/ios/helper.js old mode 100755 new mode 100644 index 5b312b812..4b539774d --- a/scripts/ios/helper.js +++ b/scripts/ios/helper.js @@ -34,7 +34,7 @@ module.exports = { xcodeProject.parseSync(); // Build the body of the script to be executed during the build phase. - var script = '"' + '\\"${PODS_ROOT}/Fabric/run\\"' + '"'; + var script = '"' + '\\"${PODS_ROOT}/FirebaseCrashlytics/run\\"' + '"'; // Generate a unique ID for our new build phase. var id = xcodeProject.generateUuid(); @@ -139,20 +139,27 @@ module.exports = { ensureRunpathSearchPath: function(context, xcodeProjectPath){ function addRunpathSearchBuildProperty(proj, build) { - const LD_RUNPATH_SEARCH_PATHS = proj.getBuildProperty("LD_RUNPATH_SEARCH_PATHS", build); - if (!LD_RUNPATH_SEARCH_PATHS) { - proj.addBuildProperty("LD_RUNPATH_SEARCH_PATHS", "\"$(inherited) @executable_path/Frameworks\"", build); - } - if (LD_RUNPATH_SEARCH_PATHS.indexOf("@executable_path/Frameworks") == -1) { - var newValue = LD_RUNPATH_SEARCH_PATHS.substr(0, LD_RUNPATH_SEARCH_PATHS.length - 1); - newValue += ' @executable_path/Frameworks\"'; - proj.updateBuildProperty("LD_RUNPATH_SEARCH_PATHS", newValue, build); - } - if (LD_RUNPATH_SEARCH_PATHS.indexOf("$(inherited)") == -1) { - var newValue = LD_RUNPATH_SEARCH_PATHS.substr(0, LD_RUNPATH_SEARCH_PATHS.length - 1); - newValue += ' $(inherited)\"'; - proj.updateBuildProperty("LD_RUNPATH_SEARCH_PATHS", newValue, build); + let LD_RUNPATH_SEARCH_PATHS = proj.getBuildProperty("LD_RUNPATH_SEARCH_PATHS", build); + + if (!Array.isArray(LD_RUNPATH_SEARCH_PATHS)) { + LD_RUNPATH_SEARCH_PATHS = [LD_RUNPATH_SEARCH_PATHS]; } + + LD_RUNPATH_SEARCH_PATHS.forEach(LD_RUNPATH_SEARCH_PATH => { + if (!LD_RUNPATH_SEARCH_PATH) { + proj.addBuildProperty("LD_RUNPATH_SEARCH_PATHS", "\"$(inherited) @executable_path/Frameworks\"", build); + } + if (LD_RUNPATH_SEARCH_PATH.indexOf("@executable_path/Frameworks") == -1) { + var newValue = LD_RUNPATH_SEARCH_PATH.substr(0, LD_RUNPATH_SEARCH_PATH.length - 1); + newValue += ' @executable_path/Frameworks\"'; + proj.updateBuildProperty("LD_RUNPATH_SEARCH_PATHS", newValue, build); + } + if (LD_RUNPATH_SEARCH_PATH.indexOf("$(inherited)") == -1) { + var newValue = LD_RUNPATH_SEARCH_PATH.substr(0, LD_RUNPATH_SEARCH_PATH.length - 1); + newValue += ' $(inherited)\"'; + proj.updateBuildProperty("LD_RUNPATH_SEARCH_PATHS", newValue, build); + } + }); } // Read and parse the XCode project (.pxbproj) from disk. @@ -200,6 +207,10 @@ module.exports = { googlePlist["FIREBASE_CRASHLYTICS_COLLECTION_ENABLED"] = (pluginVariables['FIREBASE_CRASHLYTICS_COLLECTION_ENABLED'] !== "false" ? "true" : "false") ; googlePlistModified = true; } + if(typeof pluginVariables['IOS_SHOULD_ESTABLISH_DIRECT_CHANNEL'] !== 'undefined'){ + appPlist["shouldEstablishDirectChannel"] = (pluginVariables['IOS_SHOULD_ESTABLISH_DIRECT_CHANNEL'] === "true") ; + appPlistModified = true; + } if(pluginVariables['SETUP_RECAPTCHA_VERIFICATION'] === 'true'){ var reversedClientId = googlePlist['REVERSED_CLIENT_ID']; diff --git a/src/android/FirebasePlugin.java b/src/android/FirebasePlugin.java old mode 100755 new mode 100644 index c96c45f1c..1af7c81e6 --- a/src/android/FirebasePlugin.java +++ b/src/android/FirebasePlugin.java @@ -21,7 +21,7 @@ import android.util.Base64; import android.util.Log; -import com.crashlytics.android.Crashlytics; +import com.google.firebase.crashlytics.FirebaseCrashlytics; import com.google.android.gms.auth.api.Auth; import com.google.android.gms.auth.api.signin.GoogleSignIn; @@ -62,8 +62,6 @@ import com.google.firebase.perf.FirebasePerformance; import com.google.firebase.perf.metrics.Trace; -import io.fabric.sdk.android.Fabric; - import org.apache.cordova.CallbackContext; import org.apache.cordova.CordovaInterface; import org.apache.cordova.CordovaPlugin; @@ -99,6 +97,7 @@ public class FirebasePlugin extends CordovaPlugin { protected static FirebasePlugin instance = null; private FirebaseAnalytics mFirebaseAnalytics; + private FirebaseCrashlytics firebaseCrashlytics; private FirebaseFirestore firestore; private Gson gson; private FirebaseAuth.AuthStateListener authStateListener; @@ -138,6 +137,7 @@ protected void pluginInitialize() { applicationContext = cordovaActivity.getApplicationContext(); final Bundle extras = cordovaActivity.getIntent().getExtras(); FirebasePlugin.cordovaInterface = this.cordova; + firebaseCrashlytics = FirebaseCrashlytics.getInstance(); this.cordova.getThreadPool().execute(new Runnable() { public void run() { try { @@ -146,7 +146,7 @@ public void run() { if(!getMetaDataFromManifest(CRASHLYTICS_COLLECTION_ENABLED)){ isCrashlyticsEnabled = getPreference(CRASHLYTICS_COLLECTION_ENABLED); if(isCrashlyticsEnabled){ - Fabric.with(applicationContext, new Crashlytics()); + firebaseCrashlytics.setCrashlyticsCollectionEnabled(true); } }else{ isCrashlyticsEnabled = true; @@ -758,7 +758,7 @@ public void run() { Log.e(TAG, message); callbackContext.success(1); }else{ - callbackContext.error("Cannot log error - Crashlytics collection is disabled"); + callbackContext.error("Cannot log error - firebaseCrashlytics collection is disabled"); } } catch (Exception e) { logExceptionToCrashlytics(e); @@ -776,7 +776,7 @@ private void logMessage(final JSONArray data, logMessageToCrashlytics(message); callbackContext.success(); }else{ - callbackContext.error("Cannot log message - Crashlytics collection is disabled"); + callbackContext.error("Cannot log message - firebaseCrashlytics collection is disabled"); } } @@ -797,10 +797,10 @@ private void setCrashlyticsUserId(final CallbackContext callbackContext, final S public void run() { try { if(isCrashlyticsEnabled){ - Crashlytics.setUserIdentifier(userId); + firebaseCrashlytics.setUserId(userId); callbackContext.success(); }else{ - callbackContext.error("Cannot set Crashlytics user ID - Crashlytics collection is disabled"); + callbackContext.error("Cannot set firebaseCrashlytics user ID - firebaseCrashlytics collection is disabled"); } } catch (Exception e) { handleExceptionWithContext(e, callbackContext); @@ -1102,7 +1102,7 @@ private void extractAndReturnUserInfo(final CallbackContext callbackContext) thr returnResults.put("phoneNumber", user.getPhoneNumber()); returnResults.put("photoUrl", user.getPhotoUrl() == null ? null : user.getPhotoUrl().toString()); returnResults.put("uid", user.getUid()); - returnResults.put("providerId", user.getProviderId()); + returnResults.put("providerId", user.getIdToken(false).getResult().getSignInProvider()); returnResults.put("isAnonymous", user.isAnonymous()); user.getIdToken(true).addOnSuccessListener(new OnSuccessListener() { @@ -1782,11 +1782,11 @@ private void setCrashlyticsCollectionEnabled(final CallbackContext callbackConte public void run() { try { if(getMetaDataFromManifest(CRASHLYTICS_COLLECTION_ENABLED)){ - callbackContext.error("Cannot set Crashlytics data collection at runtime as it's hard-coded to ENABLED at build-time in the manifest"); + callbackContext.error("Cannot set firebaseCrashlytics data collection at runtime as it's hard-coded to ENABLED at build-time in the manifest"); }else if(enabled && getPreference(CRASHLYTICS_COLLECTION_ENABLED)){ - callbackContext.error("Crashlytics data collection is already set to enabled"); + callbackContext.error("firebaseCrashlytics data collection is already set to enabled"); }else if(!enabled && !getPreference(CRASHLYTICS_COLLECTION_ENABLED)){ - callbackContext.error("Crashlytics data collection is already set to disabled"); + callbackContext.error("firebaseCrashlytics data collection is already set to disabled"); }else{ setPreference(CRASHLYTICS_COLLECTION_ENABLED, enabled); callbackContext.success(); @@ -2260,7 +2260,7 @@ public void run() { for(int i = 0; i < filters.length(); i++) { JSONArray filter = filters.getJSONArray(i); switch(filter.getString(0)) { - case "where": + case "where": if (Objects.equals(filter.getString(2), new String("=="))) { query = query.whereEqualTo(filter.getString(1), filter.getString(3)); } @@ -2280,7 +2280,7 @@ public void run() { query = query.whereArrayContains(filter.getString(1), filter.getString(3)); } break; - case "orderBy": + case "orderBy": Direction direction = Direction.ASCENDING; if (Objects.equals(filter.getString(2), new String("desc"))) { direction = Direction.DESCENDING; @@ -2298,7 +2298,7 @@ public void run() { break; } } - + query.get() .addOnCompleteListener(new OnCompleteListener() { @Override @@ -2509,24 +2509,24 @@ private JSONObject mapToJsonObject(Map map) throws JSONException private void logMessageToCrashlytics(String message){ if(isCrashlyticsEnabled){ try{ - Crashlytics.log(message); + firebaseCrashlytics.log(message); }catch (Exception e){ Log.e(TAG, e.getMessage()); } }else{ - Log.e(TAG, "Cannot log message - Crashlytics collection is disabled"); + Log.e(TAG, "Cannot log message - firebaseCrashlytics collection is disabled"); } } private void logExceptionToCrashlytics(Exception exception){ if(isCrashlyticsEnabled){ try{ - Crashlytics.logException(exception); + firebaseCrashlytics.recordException(exception); }catch (Exception e){ Log.e(TAG, e.getMessage()); } }else{ - Log.e(TAG, "Cannot log exception - Crashlytics collection is disabled"); + Log.e(TAG, "Cannot log exception - firebaseCrashlytics collection is disabled"); } } } diff --git a/src/android/FirebasePluginMessagingService.java b/src/android/FirebasePluginMessagingService.java old mode 100755 new mode 100644 index 3f385d94f..92e6aafb3 --- a/src/android/FirebasePluginMessagingService.java +++ b/src/android/FirebasePluginMessagingService.java @@ -17,7 +17,7 @@ import android.content.ContentResolver; import android.graphics.Color; -import com.crashlytics.android.Crashlytics; +import com.google.firebase.crashlytics.FirebaseCrashlytics; import com.google.firebase.messaging.FirebaseMessagingService; import com.google.firebase.messaging.RemoteMessage; diff --git a/src/android/build.gradle b/src/android/build.gradle old mode 100755 new mode 100644 index 0befc68a3..b08cef742 --- a/src/android/build.gradle +++ b/src/android/build.gradle @@ -1,16 +1,13 @@ buildscript { repositories { google() - maven { - url "https://maven.fabric.io/public" - } mavenCentral() jcenter() } dependencies { - classpath "io.fabric.tools:gradle:1.30.0" classpath 'com.android.tools.build:gradle:3.4.1' classpath 'com.google.gms:google-services:4.2.0' + classpath 'com.google.firebase:firebase-crashlytics-gradle:2.1.1' } } repositories { @@ -35,11 +32,16 @@ cdvPluginPostBuildExtras.add({ } // Use class instead of id (string) to be able to apply plugin from non-root gradle file - apply plugin: com.crashlytics.tools.gradle.CrashlyticsPlugin + apply plugin: com.google.firebase.crashlytics.buildtools.gradle.CrashlyticsPlugin - // Enable Crashlytics NDK reporting - crashlytics { - enableNdk true + android { + buildTypes { + release { + firebaseCrashlytics { + nativeSymbolUploadEnabled true + } + } + } } }) diff --git a/src/ios/AppDelegate+FirebasePlugin.h b/src/ios/AppDelegate+FirebasePlugin.h old mode 100755 new mode 100644 index 461b17e40..0a93f08da --- a/src/ios/AppDelegate+FirebasePlugin.h +++ b/src/ios/AppDelegate+FirebasePlugin.h @@ -1,11 +1,11 @@ -#import "AppDelegate.h" -#import - -@import UserNotifications; -@import AuthenticationServices; - -@interface AppDelegate (FirebasePlugin) -+ (AppDelegate *) instance; -@property (nonatomic, strong) NSNumber * _Nonnull applicationInBackground; -@property (NS_NONATOMIC_IOSONLY, nullable, weak) id delegate; -@end +#import "AppDelegate.h" +#import + +@import UserNotifications; +@import AuthenticationServices; + +@interface AppDelegate (FirebasePlugin) ++ (AppDelegate *) instance; +@property (nonatomic, strong) NSNumber * _Nonnull applicationInBackground; +@property (NS_NONATOMIC_IOSONLY, nullable, weak) id delegate; +@end diff --git a/src/ios/AppDelegate+FirebasePlugin.m b/src/ios/AppDelegate+FirebasePlugin.m index 98d52701b..d6fd6d74a 100644 --- a/src/ios/AppDelegate+FirebasePlugin.m +++ b/src/ios/AppDelegate+FirebasePlugin.m @@ -1,7 +1,6 @@ #import "AppDelegate+FirebasePlugin.h" #import "FirebasePlugin.h" #import "Firebase.h" -#import #import @@ -27,6 +26,7 @@ + (AppDelegate*) instance { static NSDictionary* mutableUserInfo; static FIRAuthStateDidChangeListenerHandle authStateChangeListener; static bool authStateChangeListenerInitialized = false; +static bool shouldEstablishDirectChannel = false; - (void)setDelegate:(id)delegate { objc_setAssociatedObject(self, kDelegateKey, delegate, OBJC_ASSOCIATION_RETAIN_NONATOMIC); @@ -52,43 +52,45 @@ - (NSNumber *)applicationInBackground { - (BOOL)application:(UIApplication *)application swizzledDidFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [self application:application swizzledDidFinishLaunchingWithOptions:launchOptions]; - + @try{ instance = self; - + // get GoogleService-Info.plist file path NSString *filePath = [[NSBundle mainBundle] pathForResource:@"GoogleService-Info" ofType:@"plist"]; - + // if file is successfully found, use it if(filePath){ [FirebasePlugin.firebasePlugin _logMessage:@"GoogleService-Info.plist found, setup: [FIRApp configureWithOptions]"]; // create firebase configure options passing .plist as content FIROptions *options = [[FIROptions alloc] initWithContentsOfFile:filePath]; - + // configure FIRApp with options [FIRApp configureWithOptions:options]; if([FirebasePlugin.firebasePlugin _shouldEnableCrashlytics]){ - [Fabric with:@[[Crashlytics class]]]; + [FIRApp configure]; } } - + // no .plist found, try default App if (![FIRApp defaultApp] && !filePath) { [FirebasePlugin.firebasePlugin _logError:@"GoogleService-Info.plist NOT FOUND, setup: [FIRApp defaultApp]"]; [FIRApp configure]; } + shouldEstablishDirectChannel = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"shouldEstablishDirectChannel"] boolValue]; + // Set FCM messaging delegate [FIRMessaging messaging].delegate = self; - [FIRMessaging messaging].shouldEstablishDirectChannel = true; - + [FIRMessaging messaging].shouldEstablishDirectChannel = shouldEstablishDirectChannel; + // Setup Firestore [FirebasePlugin setFirestore:[FIRFirestore firestore]]; - + // Setup Google SignIn [GIDSignIn sharedInstance].clientID = [FIRApp defaultApp].options.clientID; [GIDSignIn sharedInstance].delegate = self; - + authStateChangeListener = [[FIRAuth auth] addAuthStateDidChangeListener:^(FIRAuth * _Nonnull auth, FIRUser * _Nullable user) { @try { if(!authStateChangeListenerInitialized){ @@ -100,7 +102,7 @@ - (BOOL)application:(UIApplication *)application swizzledDidFinishLaunchingWithO [FirebasePlugin.firebasePlugin handlePluginExceptionWithoutContext:exception]; } }]; - + // Set UNUserNotificationCenter delegate self.delegate = [UNUserNotificationCenter currentNotificationCenter].delegate; [UNUserNotificationCenter currentNotificationCenter].delegate = self; @@ -110,7 +112,7 @@ - (BOOL)application:(UIApplication *)application swizzledDidFinishLaunchingWithO name:kFIRInstanceIDTokenRefreshNotification object:nil]; self.applicationInBackground = @(YES); - + }@catch (NSException *exception) { [FirebasePlugin.firebasePlugin handlePluginExceptionWithoutContext:exception]; } @@ -119,15 +121,15 @@ - (BOOL)application:(UIApplication *)application swizzledDidFinishLaunchingWithO } - (void)applicationDidBecomeActive:(UIApplication *)application { - [FIRMessaging messaging].shouldEstablishDirectChannel = true; self.applicationInBackground = @(NO); - [FirebasePlugin.firebasePlugin _logMessage:@"FCM direct channel = true"]; + [FIRMessaging messaging].shouldEstablishDirectChannel = shouldEstablishDirectChannel; + [FirebasePlugin.firebasePlugin _logMessage:[NSString stringWithFormat:@"Enter foreground: FCM direct channel = %@", shouldEstablishDirectChannel ? @"true" : @"false"]]; } - (void)applicationDidEnterBackground:(UIApplication *)application { - [FIRMessaging messaging].shouldEstablishDirectChannel = false; self.applicationInBackground = @(YES); - [FirebasePlugin.firebasePlugin _logMessage:@"FCM direct channel = false"]; + [FIRMessaging messaging].shouldEstablishDirectChannel = false; + [FirebasePlugin.firebasePlugin _logMessage:@"Enter background: FCM direct channel = false"]; } # pragma mark - Google SignIn @@ -141,7 +143,7 @@ - (void)signIn:(GIDSignIn *)signIn FIRAuthCredential *credential = [FIRGoogleAuthProvider credentialWithIDToken:authentication.idToken accessToken:authentication.accessToken]; - + int key = [[FirebasePlugin firebasePlugin] saveAuthCredential:credential]; NSMutableDictionary* result = [[NSMutableDictionary alloc] init]; [result setValue:@"true" forKey:@"instantVerification"]; @@ -207,7 +209,7 @@ - (void)application:(UIApplication *)application didRegisterForRemoteNotificatio [FIRMessaging messaging].APNSToken = deviceToken; [FirebasePlugin.firebasePlugin _logMessage:[NSString stringWithFormat:@"didRegisterForRemoteNotificationsWithDeviceToken: %@", deviceToken]]; [FirebasePlugin.firebasePlugin sendApnsToken:[FirebasePlugin.firebasePlugin hexadecimalStringFromData:deviceToken]]; - + // Set UNUserNotificationCenter delegate [UNUserNotificationCenter currentNotificationCenter].delegate = self; } @@ -235,7 +237,7 @@ - (void)application:(UIApplication *)application didReceiveRemoteNotification:(N } [FirebasePlugin.firebasePlugin _logMessage:[NSString stringWithFormat:@"didReceiveRemoteNotification: %@", mutableUserInfo]]; - + completionHandler(UIBackgroundFetchResultNewData); if([self.applicationInBackground isEqual:[NSNumber numberWithBool:YES]] && isContentAvailable){ [FirebasePlugin.firebasePlugin _logError:@"didReceiveRemoteNotification: omitting foreground notification as content-available:1 so system notification will be shown"]; @@ -255,11 +257,11 @@ - (void)application:(UIApplication *)application didReceiveRemoteNotification:(N - (void)messaging:(FIRMessaging *)messaging didReceiveMessage:(FIRMessagingRemoteMessage *)remoteMessage { @try{ [FirebasePlugin.firebasePlugin _logMessage:[NSString stringWithFormat:@"didReceiveMessage: %@", remoteMessage.appData]]; - + NSDictionary* appData = [remoteMessage.appData mutableCopy]; [appData setValue:@"data" forKey:@"messageType"]; [self processMessageForForegroundNotification:appData]; - + // This will allow us to handle FCM data-only push messages even if the permission for push // notifications is yet missing. This will only work when the app is in the foreground. [FirebasePlugin.firebasePlugin sendNotification:appData]; @@ -275,12 +277,12 @@ -(void)processMessageForForegroundNotification:(NSDictionary*)messageData { if(!showForegroundNotification){ return; } - + NSString* title = nil; NSString* body = nil; NSString* sound = nil; NSNumber* badge = nil; - + // Extract APNS notification keys NSDictionary* aps = [messageData objectForKey:@"aps"]; if([aps objectForKey:@"alert"] != nil){ @@ -298,7 +300,7 @@ -(void)processMessageForForegroundNotification:(NSDictionary*)messageData { badge = [aps objectForKey:@"badge"]; } } - + // Extract data notification keys if([messageData objectForKey:@"notification_title"] != nil){ title = [messageData objectForKey:@"notification_title"]; @@ -312,18 +314,18 @@ -(void)processMessageForForegroundNotification:(NSDictionary*)messageData { if([messageData objectForKey:@"notification_ios_badge"] != nil){ badge = [messageData objectForKey:@"notification_ios_badge"]; } - + if(title == nil || body == nil){ return; } - + [[UNUserNotificationCenter currentNotificationCenter] getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) { @try{ if (settings.alertSetting == UNNotificationSettingEnabled) { UNMutableNotificationContent *objNotificationContent = [[UNMutableNotificationContent alloc] init]; objNotificationContent.title = [NSString localizedUserNotificationStringForKey:title arguments:nil]; objNotificationContent.body = [NSString localizedUserNotificationStringForKey:body arguments:nil]; - + NSDictionary* alert = [[NSDictionary alloc] initWithObjectsAndKeys: title, @"title", body, @"body" @@ -331,7 +333,7 @@ -(void)processMessageForForegroundNotification:(NSDictionary*)messageData { NSMutableDictionary* aps = [[NSMutableDictionary alloc] initWithObjectsAndKeys: alert, @"alert", nil]; - + if(![sound isKindOfClass:[NSString class]] || [sound isEqualToString:@"default"]){ objNotificationContent.sound = [UNNotificationSound defaultSound]; [aps setValue:sound forKey:@"sound"]; @@ -339,24 +341,24 @@ -(void)processMessageForForegroundNotification:(NSDictionary*)messageData { objNotificationContent.sound = [UNNotificationSound soundNamed:sound]; [aps setValue:sound forKey:@"sound"]; } - + if(badge != nil){ [aps setValue:badge forKey:@"badge"]; } - + NSString* messageType = @"data"; if([mutableUserInfo objectForKey:@"messageType"] != nil){ messageType = [mutableUserInfo objectForKey:@"messageType"]; } - + NSDictionary* userInfo = [[NSDictionary alloc] initWithObjectsAndKeys: @"true", @"notification_foreground", messageType, @"messageType", aps, @"aps" , nil]; - + objNotificationContent.userInfo = userInfo; - + UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:0.1f repeats:NO]; UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"local_notification" content:objNotificationContent trigger:trigger]; [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { @@ -384,7 +386,7 @@ - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotif - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler { - + @try{ [self.delegate userNotificationCenter:center willPresentNotification:notification @@ -394,11 +396,11 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center [FirebasePlugin.firebasePlugin _logError:@"willPresentNotification: aborting as not a supported UNNotificationTrigger"]; return; } - + [[FIRMessaging messaging] appDidReceiveMessage:notification.request.content.userInfo]; - + mutableUserInfo = [notification.request.content.userInfo mutableCopy]; - + NSString* messageType = [mutableUserInfo objectForKey:@"messageType"]; if(![messageType isEqualToString:@"data"]){ [mutableUserInfo setValue:@"notification" forKey:@"messageType"]; @@ -407,14 +409,14 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center // Print full message. [FirebasePlugin.firebasePlugin _logMessage:[NSString stringWithFormat:@"willPresentNotification: %@", mutableUserInfo]]; - + NSDictionary* aps = [mutableUserInfo objectForKey:@"aps"]; bool isContentAvailable = [[aps objectForKey:@"content-available"] isEqualToNumber:[NSNumber numberWithInt:1]]; if(isContentAvailable){ [FirebasePlugin.firebasePlugin _logError:@"willPresentNotification: aborting as content-available:1 so system notification will be shown"]; return; } - + bool showForegroundNotification = [mutableUserInfo objectForKey:@"notification_foreground"]; bool hasAlert = [aps objectForKey:@"alert"] != nil; bool hasBadge = [aps objectForKey:@"badge"] != nil; @@ -440,11 +442,11 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center }else{ [FirebasePlugin.firebasePlugin _logMessage:@"willPresentNotification: foreground notification not set"]; } - + if(![messageType isEqualToString:@"data"]){ [FirebasePlugin.firebasePlugin sendNotification:mutableUserInfo]; } - + }@catch (NSException *exception) { [FirebasePlugin.firebasePlugin handlePluginExceptionWithoutContext:exception]; } @@ -467,21 +469,21 @@ - (void) userNotificationCenter:(UNUserNotificationCenter *)center } [[FIRMessaging messaging] appDidReceiveMessage:response.notification.request.content.userInfo]; - + mutableUserInfo = [response.notification.request.content.userInfo mutableCopy]; - + NSString* tap; if([self.applicationInBackground isEqual:[NSNumber numberWithBool:YES]]){ tap = @"background"; }else{ tap = @"foreground"; - + } [mutableUserInfo setValue:tap forKey:@"tap"]; if([mutableUserInfo objectForKey:@"messageType"] == nil){ [mutableUserInfo setValue:@"notification" forKey:@"messageType"]; } - + // Print full message. [FirebasePlugin.firebasePlugin _logInfo:[NSString stringWithFormat:@"didReceiveNotificationResponse: %@", mutableUserInfo]]; @@ -489,7 +491,7 @@ - (void) userNotificationCenter:(UNUserNotificationCenter *)center [FirebasePlugin.firebasePlugin sendNotification:mutableUserInfo]; completionHandler(); - + }@catch (NSException *exception) { [FirebasePlugin.firebasePlugin handlePluginExceptionWithoutContext:exception]; } @@ -508,7 +510,7 @@ - (void)authorizationController:(ASAuthorizationController *)controller CDVPluginResult* pluginResult; NSString* errorMessage = nil; FIROAuthCredential *credential; - + if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) { ASAuthorizationAppleIDCredential *appleIDCredential = authorization.credential; NSString *rawNonce = [FirebasePlugin appleSignInNonce]; @@ -526,7 +528,7 @@ - (void)authorizationController:(ASAuthorizationController *)controller credential = [FIROAuthProvider credentialWithProviderID:@"apple.com" IDToken:idToken rawNonce:rawNonce]; - + int key = [[FirebasePlugin firebasePlugin] saveAuthCredential:credential]; NSMutableDictionary* result = [[NSMutableDictionary alloc] init]; [result setValue:@"true" forKey:@"instantVerification"]; diff --git a/src/ios/FirebasePlugin.m b/src/ios/FirebasePlugin.m index 4cb35cdf1..1a184a1f1 100644 --- a/src/ios/FirebasePlugin.m +++ b/src/ios/FirebasePlugin.m @@ -3,7 +3,6 @@ #import "AppDelegate+FirebasePlugin.h" #import #import "AppDelegate.h" -#import #import @import FirebaseInstanceID; @import FirebaseMessaging; @@ -57,31 +56,31 @@ + (void) setFirestore:(FIRFirestore*) firestoreInstance{ - (void)pluginInitialize { NSLog(@"Starting Firebase plugin"); firebasePlugin = self; - + @try { preferences = [NSUserDefaults standardUserDefaults]; googlePlist = [NSMutableDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"GoogleService-Info" ofType:@"plist"]]; - + if(![self getGooglePlistFlagWithDefaultValue:FIREBASE_CRASHLYTICS_COLLECTION_ENABLED defaultValue:YES]){ isCrashlyticsEnabled = [self getPreferenceFlag:FIREBASE_CRASHLYTICS_COLLECTION_ENABLED]; }else{ isCrashlyticsEnabled = YES; [self setPreferenceFlag:FIREBASE_CRASHLYTICS_COLLECTION_ENABLED flag:YES]; } - + if([self getGooglePlistFlagWithDefaultValue:FIREBASE_ANALYTICS_COLLECTION_ENABLED defaultValue:YES]){ [self setPreferenceFlag:FIREBASE_ANALYTICS_COLLECTION_ENABLED flag:YES]; } - + if([self getGooglePlistFlagWithDefaultValue:FIREBASE_PERFORMANCE_COLLECTION_ENABLED defaultValue:YES]){ [self setPreferenceFlag:FIREBASE_PERFORMANCE_COLLECTION_ENABLED flag:YES]; } - + // Check for permission and register for remote notifications if granted [self _hasPermission:^(BOOL result) {}]; - + [GIDSignIn sharedInstance].presentingViewController = self.viewController; - + authCredentials = [[NSMutableDictionary alloc] init]; }@catch (NSException *exception) { [self handlePluginExceptionWithoutContext:exception]; @@ -167,7 +166,7 @@ - (void)getToken:(CDVInvokedUrlCommand *)command { }else{ pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:error.description]; } - + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; }]; }@catch (NSException *exception) { @@ -200,7 +199,7 @@ - (NSString *)hexadecimalStringFromData:(NSData *)data if (dataLength == 0) { return nil; } - + const unsigned char *dataBuffer = data.bytes; NSMutableString *hexString = [NSMutableString stringWithCapacity:(dataLength * 2)]; for (int i = 0; i < dataLength; ++i) { @@ -285,7 +284,7 @@ - (void)grantPermission:(CDVInvokedUrlCommand *)command { - (void)registerForRemoteNotifications { NSLog(@"registerForRemoteNotifications"); if(registeredForRemoteNotifications) return; - + [self runOnMainThread:^{ @try { [[UIApplication sharedApplication] registerForRemoteNotifications]; @@ -317,7 +316,7 @@ - (void)getBadgeNumber:(CDVInvokedUrlCommand *)command { [self runOnMainThread:^{ @try { long badge = [[UIApplication sharedApplication] applicationIconBadgeNumber]; - + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDouble:badge]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; }@catch (NSException *exception) { @@ -476,7 +475,7 @@ - (void)clearAllNotifications:(CDVInvokedUrlCommand *)command { @try { [[UIApplication sharedApplication] setApplicationIconBadgeNumber:1]; [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0]; - + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; }@catch (NSException *exception) { @@ -593,7 +592,7 @@ - (void)authenticateUserWithGoogle:(CDVInvokedUrlCommand*)command{ @try { self.googleSignInCallbackId = command.callbackId; [[GIDSignIn sharedInstance] signIn]; - + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_NO_RESULT]; [pluginResult setKeepCallbackAsBool:YES]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; @@ -608,13 +607,13 @@ - (void)authenticateUserWithApple:(CDVInvokedUrlCommand*)command{ if (@available(iOS 13.0, *)) { self.appleSignInCallbackId = command.callbackId; [self startSignInWithAppleFlow]; - + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_NO_RESULT]; [pluginResult setKeepCallbackAsBool:YES]; } else { pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"OS version is too low - Apple Sign In requires iOS 13.0+"]; } - + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; }@catch (NSException *exception) { [self handlePluginExceptionWithContext:exception :command]; @@ -625,7 +624,7 @@ - (void)signInWithCredential:(CDVInvokedUrlCommand*)command { @try { FIRAuthCredential* credential = [self obtainAuthCredential:[command.arguments objectAtIndex:0] command:command]; if(credential == nil) return; - + [[FIRAuth auth] signInWithCredential:credential completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) { @@ -643,10 +642,10 @@ - (void)reauthenticateWithCredential:(CDVInvokedUrlCommand*)command{ [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No user is currently signed"] callbackId:command.callbackId]; return; } - + FIRAuthCredential* credential = [self obtainAuthCredential:[command.arguments objectAtIndex:0] command:command]; if(credential == nil) return; - + [user reauthenticateWithCredential:credential completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) { [self handleAuthResult:authResult error:error command:command]; }]; @@ -659,13 +658,13 @@ - (void)linkUserWithCredential:(CDVInvokedUrlCommand*)command { @try { FIRAuthCredential* credential = [self obtainAuthCredential:[command.arguments objectAtIndex:0] command:command]; if(credential == nil) return; - + [[FIRAuth auth].currentUser linkWithCredential:credential completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) { [self handleAuthResult:authResult error:error command:command]; }]; - + }@catch (NSException *exception) { [self handlePluginExceptionWithContext:exception :command]; } @@ -675,7 +674,7 @@ - (void)isUserSignedIn:(CDVInvokedUrlCommand*)command { @try { bool isSignedIn = [FIRAuth auth].currentUser ? true : false; [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:isSignedIn] callbackId:command.callbackId]; - + }@catch (NSException *exception) { [self handlePluginExceptionWithContext:exception :command]; } @@ -688,12 +687,12 @@ - (void)signOutUser:(CDVInvokedUrlCommand*)command { [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No user is currently signed"] callbackId:command.callbackId]; return; } - + // Sign out of Google if([[GIDSignIn sharedInstance] currentUser] != nil){ [[GIDSignIn sharedInstance] signOut]; } - + // Sign out of Firebase NSError *signOutError; BOOL status = [[FIRAuth auth] signOut:&signOutError]; @@ -708,7 +707,7 @@ - (void)signOutUser:(CDVInvokedUrlCommand*)command { } - (void)getCurrentUser:(CDVInvokedUrlCommand *)command { - + @try { FIRUser* user = [FIRAuth auth].currentUser; if(!user){ @@ -716,14 +715,14 @@ - (void)getCurrentUser:(CDVInvokedUrlCommand *)command { return; } [self extractAndReturnUserInfo:command]; - + }@catch (NSException *exception) { [self handlePluginExceptionWithContext:exception :command]; } } - (void)reloadCurrentUser:(CDVInvokedUrlCommand *)command { - + @try { FIRUser* user = [FIRAuth auth].currentUser; if(!user){ @@ -751,11 +750,13 @@ - (void) extractAndReturnUserInfo:(CDVInvokedUrlCommand *)command { [userInfo setValue:user.phoneNumber forKey:@"phoneNumber"]; [userInfo setValue:user.photoURL ? user.photoURL.absoluteString : nil forKey:@"photoUrl"]; [userInfo setValue:user.uid forKey:@"uid"]; - [userInfo setValue:user.providerID forKey:@"providerId"]; [userInfo setValue:@(user.isAnonymous ? true : false) forKey:@"isAnonymous"]; [user getIDTokenWithCompletion:^(NSString * _Nullable token, NSError * _Nullable error) { [userInfo setValue:token forKey:@"idToken"]; - [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:userInfo] callbackId:command.callbackId]; + [user getIDTokenResultWithCompletion:^(FIRAuthTokenResult * _Nullable tokenResult, NSError * _Nullable error) { + [userInfo setValue:tokenResult.signInProvider forKey:@"providerId"]; + [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:userInfo] callbackId:command.callbackId]; + }]; }]; } @@ -766,9 +767,9 @@ - (void)updateUserProfile:(CDVInvokedUrlCommand*)command { [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No user is currently signed"] callbackId:command.callbackId]; return; } - + NSDictionary* profile = [command.arguments objectAtIndex:0]; - + FIRUserProfileChangeRequest* changeRequest = [user profileChangeRequest]; if([profile objectForKey:@"name"] != nil){ changeRequest.displayName = [profile objectForKey:@"name"]; @@ -776,7 +777,7 @@ - (void)updateUserProfile:(CDVInvokedUrlCommand*)command { if([profile objectForKey:@"photoUri"] != nil){ changeRequest.photoURL = [NSURL URLWithString:[profile objectForKey:@"photoUri"]]; } - + [changeRequest commitChangesWithCompletion:^(NSError *_Nullable error) { @try { [self handleResultWithPotentialError:error command:command]; @@ -796,7 +797,7 @@ - (void)updateUserEmail:(CDVInvokedUrlCommand*)command { [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No user is currently signed"] callbackId:command.callbackId]; return; } - + NSString* email = [command.arguments objectAtIndex:0]; [user updateEmail:email completion:^(NSError *_Nullable error) { @try { @@ -817,7 +818,7 @@ - (void)sendUserEmailVerification:(CDVInvokedUrlCommand*)command{ [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No user is currently signed"] callbackId:command.callbackId]; return; } - + [user sendEmailVerificationWithCompletion:^(NSError *_Nullable error) { @try { [self handleResultWithPotentialError:error command:command]; @@ -837,7 +838,7 @@ - (void)updateUserPassword:(CDVInvokedUrlCommand*)command{ [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No user is currently signed"] callbackId:command.callbackId]; return; } - + NSString* password = [command.arguments objectAtIndex:0]; [user updatePassword:password completion:^(NSError *_Nullable error) { @try { @@ -873,7 +874,7 @@ - (void)deleteUser:(CDVInvokedUrlCommand*)command{ [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No user is currently signed"] callbackId:command.callbackId]; return; } - + [user deleteWithCompletion:^(NSError *_Nullable error) { @try { [self handleResultWithPotentialError:error command:command]; @@ -1064,7 +1065,7 @@ - (void)setCrashlyticsCollectionEnabled:(CDVInvokedUrlCommand *)command { [self setPreferenceFlag:FIREBASE_CRASHLYTICS_COLLECTION_ENABLED flag:enabled]; pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; } - + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; }@catch (NSException *exception) { [self handlePluginExceptionWithContext:exception :command]; @@ -1097,7 +1098,7 @@ - (void)isCrashlyticsCollectionCurrentlyEnabled:(CDVInvokedUrlCommand*)command{ - (void)logError:(CDVInvokedUrlCommand *)command { [self.commandDelegate runInBackground:^{ NSString* errorMessage = [command.arguments objectAtIndex:0]; - + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; @try { if(!isCrashlyticsEnabled){ @@ -1106,32 +1107,29 @@ - (void)logError:(CDVInvokedUrlCommand *)command { // We can optionally be passed a stack trace from stackTrace.js which we'll put in userInfo. else if ([command.arguments count] > 1) { NSArray* stackFrames = [command.arguments objectAtIndex:1]; - + NSString* message = errorMessage; NSString* name = @"Uncaught Javascript exception"; NSMutableArray *customFrames = [[NSMutableArray alloc] init]; - + FIRExceptionModel *exceptionModel = [FIRExceptionModel exceptionModelWithName:name reason:message]; + for (NSDictionary* stackFrame in stackFrames) { - CLSStackFrame *customFrame = [CLSStackFrame stackFrame]; - [customFrame setSymbol:stackFrame[@"functionName"]]; - [customFrame setFileName:stackFrame[@"fileName"]]; - [customFrame setLibrary:stackFrame[@"source"]]; - [customFrame setOffset:(uint64_t) [stackFrame[@"columnNumber"] intValue]]; - [customFrame setLineNumber:(uint32_t) [stackFrame[@"lineNumber"] intValue]]; + FIRStackFrame *customFrame = [FIRStackFrame stackFrameWithSymbol:stackFrame[@"functionName"] file:stackFrame[@"fileName"] line:(uint32_t) [stackFrame[@"lineNumber"] intValue]]; [customFrames addObject:customFrame]; } - [[Crashlytics sharedInstance] recordCustomExceptionName:name reason:message frameArray:customFrames]; + exceptionModel.stackTrace = customFrames; + [[FIRCrashlytics crashlytics] recordExceptionModel:exceptionModel]; }else{ //TODO detect and handle non-stack userInfo and pass to recordError NSMutableDictionary* userInfo = [[NSMutableDictionary alloc] init]; NSError *error = [NSError errorWithDomain:errorMessage code:0 userInfo:userInfo]; - [CrashlyticsKit recordError:error]; + [[FIRCrashlytics crashlytics] recordError:error]; } [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } @catch (NSException *exception) { [self handlePluginExceptionWithContext:exception :command]; } - + }]; } @@ -1143,7 +1141,7 @@ - (void)logMessage:(CDVInvokedUrlCommand*)command{ if(!isCrashlyticsEnabled){ pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Cannot log message - Crashlytics collection is disabled"]; }else if(message){ - CLSNSLog(@"%@",message); + [[FIRCrashlytics crashlytics] logWithFormat:@"%@", message]; } [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; }@catch (NSException *exception) { @@ -1153,7 +1151,7 @@ - (void)logMessage:(CDVInvokedUrlCommand*)command{ } - (void)sendCrash:(CDVInvokedUrlCommand*)command{ - [[Crashlytics sharedInstance] crash]; + assert(NO); } - (void)setCrashlyticsUserId:(CDVInvokedUrlCommand *)command { @@ -1163,7 +1161,7 @@ - (void)setCrashlyticsUserId:(CDVInvokedUrlCommand *)command { if(!isCrashlyticsEnabled){ pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Cannot set user ID - Crashlytics collection is disabled"]; }else{ - [CrashlyticsKit setUserIdentifier:userId]; + [[FIRCrashlytics crashlytics] setUserID:userId]; } [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; }@catch (NSException *exception) { @@ -1413,7 +1411,7 @@ - (void)setDocumentInFirestoreCollection:(CDVInvokedUrlCommand*)command { NSString* documentId = [command.arguments objectAtIndex:0]; NSDictionary* document = [command.arguments objectAtIndex:1]; NSString* collection = [command.arguments objectAtIndex:2]; - + [[[firestore collectionWithPath:collection] documentWithPath:documentId] setData:document completion:^(NSError * _Nullable error) { if (error != nil) { [self sendPluginError:error.localizedDescription:command]; @@ -1433,7 +1431,7 @@ - (void)updateDocumentInFirestoreCollection:(CDVInvokedUrlCommand*)command { NSString* documentId = [command.arguments objectAtIndex:0]; NSDictionary* document = [command.arguments objectAtIndex:1]; NSString* collection = [command.arguments objectAtIndex:2]; - + FIRDocumentReference* docRef = [[firestore collectionWithPath:collection] documentWithPath:documentId]; if(docRef != nil){ [docRef updateData:document completion:^(NSError * _Nullable error) { @@ -1477,7 +1475,7 @@ - (void)documentExistsInFirestoreCollection:(CDVInvokedUrlCommand*)command { @try { NSString* documentId = [command.arguments objectAtIndex:0]; NSString* collection = [command.arguments objectAtIndex:1]; - + FIRDocumentReference* docRef = [[firestore collectionWithPath:collection] documentWithPath:documentId]; if(docRef != nil){ [docRef getDocumentWithCompletion:^(FIRDocumentSnapshot * _Nullable snapshot, NSError * _Nullable error) { @@ -1502,7 +1500,7 @@ - (void)fetchDocumentInFirestoreCollection:(CDVInvokedUrlCommand*)command { @try { NSString* documentId = [command.arguments objectAtIndex:0]; NSString* collection = [command.arguments objectAtIndex:1]; - + FIRDocumentReference* docRef = [[firestore collectionWithPath:collection] documentWithPath:documentId]; if(docRef != nil){ [docRef getDocumentWithCompletion:^(FIRDocumentSnapshot * _Nullable snapshot, NSError * _Nullable error) { @@ -1618,27 +1616,28 @@ - (void)executeGlobalJavascript: (NSString*)jsString - (void)_logError: (NSString*)msg { NSLog(@"%@ ERROR: %@", LOG_TAG, msg); - NSString* jsString = [NSString stringWithFormat:@"console.error(\"%@: %@\")", LOG_TAG, [self escapeDoubleQuotes:msg]]; + NSString* jsString = [NSString stringWithFormat:@"console.error(\"%@: %@\")", LOG_TAG, [self escapeJavascriptString:msg]]; [self executeGlobalJavascript:jsString]; } - (void)_logInfo: (NSString*)msg { NSLog(@"%@ INFO: %@", LOG_TAG, msg); - NSString* jsString = [NSString stringWithFormat:@"console.info(\"%@: %@\")", LOG_TAG, [self escapeDoubleQuotes:msg]]; + NSString* jsString = [NSString stringWithFormat:@"console.info(\"%@: %@\")", LOG_TAG, [self escapeJavascriptString:msg]]; [self executeGlobalJavascript:jsString]; } - (void)_logMessage: (NSString*)msg { NSLog(@"%@ LOG: %@", LOG_TAG, msg); - NSString* jsString = [NSString stringWithFormat:@"console.log(\"%@: %@\")", LOG_TAG, [self escapeDoubleQuotes:msg]]; + NSString* jsString = [NSString stringWithFormat:@"console.log(\"%@: %@\")", LOG_TAG, [self escapeJavascriptString:msg]]; [self executeGlobalJavascript:jsString]; } -- (NSString*)escapeDoubleQuotes: (NSString*)str +- (NSString*)escapeJavascriptString: (NSString*)str { - NSString *result =[str stringByReplacingOccurrencesOfString: @"\"" withString: @"\\\""]; + NSString* result = [str stringByReplacingOccurrencesOfString: @"\"" withString: @"\\\""]; + result = [result stringByReplacingOccurrencesOfString: @"\n" withString: @"\\\n"]; return result; } @@ -1662,17 +1661,17 @@ - (void)runOnMainThread:(void (^)(void))completeBlock { - (FIRAuthCredential*)obtainAuthCredential:(NSDictionary*)credential command:(CDVInvokedUrlCommand *)command { FIRAuthCredential* authCredential = nil; - + if(credential == nil){ NSString* errMsg = @"credential object must be passed as first and only argument"; [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:errMsg] callbackId:command.callbackId]; return authCredential; } - + NSString* key = [credential objectForKey:@"id"]; NSString* verificationId = [credential objectForKey:@"verificationId"]; NSString* code = [credential objectForKey:@"code"]; - + if(key != nil){ authCredential = [authCredentials objectForKey:key]; if(authCredential == nil){ @@ -1712,7 +1711,7 @@ - (int) saveAuthCredential: (FIRAuthCredential*) authCredential { while (key < 0 || [authCredentials objectForKey:[NSNumber numberWithInt:key]] != nil) { key = arc4random_uniform(100000); } - + [authCredentials setObject:authCredential forKey:[NSNumber numberWithInt:key]]; return key; diff --git a/types/index.d.ts b/types/index.d.ts index e9cf84aca..d2cb96360 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -116,7 +116,7 @@ interface FirebasePlugin { stackTrace?: object, success?: () => void, error?: (err: string) => void - ) + ): void verifyPhoneNumber( success: (value: object) => void, error: (err: string) => void,