├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Gruntfile.js
├── ISSUE_TEMPLATE.md
├── LICENSE
├── PULL_REQUEST_TEMPLATE.md
├── README.md
├── firebase-crashlytics.gradle
├── package.json
├── plugin.xml
├── src
├── android
│ └── uk
│ │ └── co
│ │ └── reallysmall
│ │ └── cordova
│ │ └── plugin
│ │ └── firebase
│ │ └── crashlytics
│ │ ├── ActionHandler.java
│ │ ├── CrashHandler.java
│ │ ├── FirebaseCrashlyticsPlugin.java
│ │ ├── InitialiseHandler.java
│ │ ├── LogErrorHandler.java
│ │ ├── LogExceptionHandler.java
│ │ ├── LogHandler.java
│ │ ├── LogPriorityHandler.java
│ │ ├── SetBoolHandler.java
│ │ ├── SetDoubleHandler.java
│ │ ├── SetFloatHandler.java
│ │ ├── SetIntHandler.java
│ │ ├── SetStringHandler.java
│ │ └── SetUserIdentifierHandler.java
└── ios
│ ├── FirebaseCrashlyticsPlugin.h
│ └── FirebaseCrashlyticsPlugin.m
├── types
└── index.d.ts
└── www
├── browser
└── crashlytics.js
└── crashlytics.js
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | /test-reports/jshint.xml
3 | /package-lock.json
4 | .idea
5 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our Standards
8 |
9 | Examples of behavior that contributes to creating a positive environment include:
10 |
11 | * Using welcoming and inclusive language
12 | * Being respectful of differing viewpoints and experiences
13 | * Gracefully accepting constructive criticism
14 | * Focusing on what is best for the community
15 | * Showing empathy towards other community members
16 |
17 | Examples of unacceptable behavior by participants include:
18 |
19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances
20 | * Trolling, insulting/derogatory comments, and personal or political attacks
21 | * Public or private harassment
22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission
23 | * Other conduct which could reasonably be considered inappropriate in a professional setting
24 |
25 | ## Our Responsibilities
26 |
27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28 |
29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30 |
31 | ## Scope
32 |
33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34 |
35 | ## Enforcement
36 |
37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at richard.windley@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38 |
39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40 |
41 | ## Attribution
42 |
43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44 |
45 | [homepage]: http://contributor-covenant.org
46 | [version]: http://contributor-covenant.org/version/1/4/
47 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 | We want to make contributing to this project as easy and transparent as possible, whether it's:
3 |
4 | - Reporting a bug
5 | - Discussing the current state of the code
6 | - Submitting a fix
7 | - Proposing new features
8 |
9 | ## We Develop with Github
10 | We use github to host code, to track issues and feature requests, as well as accept pull requests.
11 |
12 | ## We Use [Github Flow](https://guides.github.com/introduction/flow/index.html), So All Code Changes Happen Through Pull Requests
13 | Pull requests are the best way to propose changes to the codebase (we use [Github Flow](https://guides.github.com/introduction/flow/index.html)). We actively welcome your pull requests:
14 |
15 | 1. Fork the repo and create your branch from `master`.
16 | 2. If you've added code that should be tested, add tests.
17 | 3. If you've changed APIs, update the documentation.
18 | 4. Ensure the test suite passes.
19 | 5. Make sure your code lints.
20 | 6. Issue that pull request!
21 |
22 | ## Any contributions you make will be under the licence specified in the LICENSE file
23 | In short, when you submit code changes, your submissions are understood to be under the same License that covers the project. Feel free to contact the maintainers if that's a concern.
24 |
25 | ## Report bugs using Github's [issues](https://github.com/ReallySmallSoftware/cordova-plugin-firebase-crashlytics/issues)
26 | We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/ReallySmallSoftware/cordova-plugin-firebase-crashlytics/issues/new); it's that easy!
27 |
28 | ## Write bug reports with detail, background, and sample code where appropriate
29 | Make sure at the very least you provide the information in the [issue template](https://github.com/ReallySmallSoftware/cordova-plugin-firebase-crashlytics/blob/master/ISSUE_TEMPLATE.md)
30 |
31 | ## Use a Consistent Coding Style
32 | The coding style should match what is present in the code currently. Do not reformat entire files.
33 |
34 | ## References
35 | This document was adapted from the open-source contribution guidelines for [Facebook's Draft](https://github.com/facebook/draft-js/blob/a9316a723f9e918afde44dea68b5f9f39b7d9b00/CONTRIBUTING.md)
36 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function(grunt) {
2 |
3 | // Project configuration.
4 | grunt.initConfig({
5 | jshint: {
6 | options: {
7 | reporter: require("jshint-junit-reporter"),
8 | reporterOutput: "test-reports/jshint.xml",
9 | curly: true,
10 | eqeqeq: true,
11 | immed: true,
12 | latedef: true,
13 | newcap: true,
14 | noarg: true,
15 | sub: true,
16 | undef: true,
17 | boss: true,
18 | eqnull: true,
19 | node: true,
20 | es5: false,
21 | globals: {
22 | jasmine: false,
23 | describe: false,
24 | beforeEach: false,
25 | afterEach: false,
26 | expect: false,
27 | it: false,
28 | spyOn: false,
29 | $: false,
30 | cordova: false,
31 | launchnavigator: false,
32 | window: false,
33 | document: false,
34 | ons: false,
35 | navigator: false,
36 | google: false,
37 | FCMPlugin: false,
38 | device: false,
39 | plugins: false,
40 | addFixture: false,
41 | truncateSql: false
42 | }
43 | },
44 | all: ['Gruntfile.js', 'www/**/*.js']
45 | }
46 | });
47 |
48 | grunt.loadNpmTasks('grunt-contrib-jshint');
49 | };
50 |
--------------------------------------------------------------------------------
/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## Expected Behavior
2 |
3 |
4 | ## Actual Behavior
5 |
6 |
7 | ## Steps to Reproduce the Problem
8 |
9 |
10 | ## Specifications
11 |
12 | - Plugin version:
13 | - Framework:
14 | - Framework version:
15 | - Operating system:
16 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2017 Richard Windley
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 |
--------------------------------------------------------------------------------
/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | Fixes #
2 |
3 | ## Proposed Changes
4 |
5 | -
6 | -
7 | -
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Cordova Firebase Crashlytics Plugin
2 |
3 | A Google Firebase Crashlytics plugin to enable capture of crash reports.
4 |
5 | # What is Crashlytics?
6 |
7 | From the Google documentation (https://firebase.google.com/products/crashlytics/):
8 |
9 | > Firebase Crashlytics helps you track, prioritize, and fix stability issues that erode app quality, in realtime. Spend less time triaging and troubleshooting crashes and more time building app features that delight users
10 |
11 | # Supported platforms
12 | This plugin supports the following platforms:
13 |
14 | - Android
15 | - iOS (untested)
16 | - Browser (for testing only)
17 |
18 | # Installation
19 |
20 | `cordova plugin add cordova-plugin-firebase-crashlytics --variable ANDROID_FIREBASE_CORE_VERSION=16.0.0 --save`
21 |
22 | or
23 |
24 | `phonegap plugin add cordova-plugin-firebase-crashlytics --variable ANDROID_FIREBASE_CORE_VERSION=16.0.0`
25 |
26 | Omitting `FIREBASE_VERSION` will use a default value.
27 |
28 | ## Firebase configuration
29 | ### Android
30 |
31 | You must ensure that `google-services.json` is put in the correct location. This can be achieved using the following in your `config.xml`:
32 |
33 | ```
34 |
35 |
36 |
37 | ```
38 |
39 | #### Dependencies
40 | ##### cordova-support-google-services
41 |
42 | In order to ensure Firebase initialises correctly on Android this plugin can be used. This is not automatically added as a dependency to allow for the configuration it performs to be done manually if desired.
43 |
44 | ### iOS
45 | iOS requires `GoogleService-Info.plist` is put in the correct location. Similarly this can be done as follows:
46 | ```
47 |
48 |
49 |
50 | ```
51 |
52 | #### Podfile configuration
53 | At this time it is necessary to manually add the `use_frameworks!` directive to this file.
54 |
55 | #### Keychain Sharing Capability
56 | If using multiple Firebase plugins it may be necessary to enable this.
57 |
58 | # How to use it
59 | Simply add the plugin to get the default Crashlytics functionality. Note that crashes and logged exceptions will only be reported when the application restarts.
60 |
61 | In order to log caught exceptions the following can be used:
62 |
63 | ```
64 | var crashlytics = FirebaseCrashlytics.initialise();
65 | crashlytics.logException("my caught exception");
66 | ```
67 |
68 | ## Methods
69 | ### crash()
70 | Generate a forced crash. Visible in console after restart of application.
71 |
72 | ### logPriority(priority, tag, message)
73 | Log a priority message. Will only be logged in the event of a crash.
74 |
75 | Available priorities are compatible with most Android [Log constants](https://developer.android.com/reference/android/util/Log#constants_2):
76 | - FirebaseCrashlytics.LOG.VERBOSE
77 | - FirebaseCrashlytics.LOG.DEBUG
78 | - FirebaseCrashlytics.LOG.INFO
79 | - FirebaseCrashlytics.LOG.WARN
80 | - FirebaseCrashlytics.LOG.ERROR
81 |
82 | Example usage
83 | ```js
84 | crashlytics.logPriority(FirebaseCrashlytics.LOG.WARN, 'dashboard', 'This should not happened')
85 | ```
86 |
87 | ### initialise(hasConsent):Promise
88 | Initialise Crashlytics and send any logs files if the user has given consent, otherwise delete them.
89 |
90 | Returns a true if there was a previous crash.
91 |
92 | ### log(message)
93 | Log a message. Will only be logged in the event of a crash.
94 |
95 | ### logException(message)
96 | Log when a handled exception has happened. Visible in console after restart of application.
97 |
98 | ### setString(key, value)
99 | Set extra key/value string value. Will only be logged in the event of a crash.
100 |
101 | ### setBool(key, value)
102 | Set extra key/value bool value. Will only be logged in the event of a crash.
103 |
104 | ### setDouble(key, value)
105 | Set extra key/value double value. Will only be logged in the event of a crash.
106 |
107 | ### setFloat(key, value)
108 | Set extra key/value float value. Will only be logged in the event of a crash.
109 |
110 | ### setInt(key, value)
111 | Set extra key/value integer value. Will only be logged in the event of a crash.
112 |
113 | ### setUserIdentifier(identifier)
114 | Set the identifier for the user. Take care when using this method and ensure you privacy policy is updated accordingly.
115 |
116 | ## Typescript
117 | Support is now included for typescript. Use the following to reference the typescript definitions:
118 |
119 | ```
120 | ///
121 |
122 | private static crashlytics: FirebaseCrashlytics.FirebaseCrashlytics = FirebaseCrashlytics.initialise();
123 | crashlytics.logException("my message");
124 | ```
125 |
126 | You may also need to add an external to webpack.config.ls:
127 |
128 | ```
129 | externals: {
130 | 'cordova-plugin-firebase-crashlytics': "cordova-plugin-firebase-crashlytics"
131 | '/exec':"cordova/exec"
132 | },
133 | ```
134 |
135 | ## 1.1.0
136 | - Update dependencies
137 | - Refactor Android and iOS code
138 | - Add initialise method to give consent for uploading logs
139 |
140 | ## 1.0.0
141 | - Added types
142 | - Updated dependencies for iOS
143 | - Updated dependencies for Android
144 |
145 | ## 0.1.0
146 | - Dependency updates
147 | - Addition of log priority constants
148 |
149 | ## 0.0.9
150 | - Update Android Firebase dependency
151 | - Fix podspec for cordova-ios 5
152 | - Fix xcode issue
153 |
154 | ## 0.0.8
155 | - Remove podspec version for firebase
156 |
157 | ## 0.0.7
158 | - Update Android dependency versions
159 | - Update iOS dependency versions
160 | - Update plugin dependencies
161 | - WARNING: The Android update may require you to update com.google.gms:google-services to 4.0.0, com.android.tools.build:gradle to 3.1.2 and gradle to 4.4.4 (look in platforms/android/cordova/lib/builders/GradleBuilder.js)
162 |
163 | ## 0.0.6
164 | - Add SetUserIdentifier()
165 | - Fix iOS set() methods with wrong types
166 |
167 | ## 0.0.5
168 | - Merge back in some iOS updates (https://github.com/kanodeveloper/cordova-plugin-firebase-crashlytics-ka)
169 | - Add xcode npm dependency
170 |
171 | ## 0.0.4
172 | - Updated gradle dependencies
173 |
174 | ## 0.0.3
175 | - Fix typo in README
176 | - Added embarrassing fix for logException()
177 |
178 | ## 0.0.2
179 | - Add grunt to run jshint
180 | - Fix some grunt warnings
181 |
182 | ## 0.0.1
183 | - Initial release
184 |
--------------------------------------------------------------------------------
/firebase-crashlytics.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | google()
4 | mavenCentral()
5 | }
6 | dependencies {
7 | classpath 'com.google.gms:google-services:4.3.3'
8 | classpath 'com.google.firebase:firebase-crashlytics-gradle:2.2.0'
9 | }
10 | }
11 |
12 | allprojects {
13 | repositories {
14 | google()
15 | }
16 | }
17 |
18 | ext.postBuildExtras = {
19 | apply plugin: com.google.firebase.crashlytics.buildtools.gradle.CrashlyticsPlugin
20 | }
21 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cordova-plugin-firebase-crashlytics",
3 | "version": "1.2.0",
4 | "cordova": {
5 | "id": "cordova-plugin-firebase-crashlytics",
6 | "platforms": [
7 | "android",
8 | "ios",
9 | "browser"
10 | ]
11 | },
12 | "types": "./types/index.d.ts",
13 | "engines": {
14 | "cordovaDependencies": {
15 | "0.0.7": {
16 | "cordova": ">=7.0.0",
17 | "cordova-android": ">=8.0.0",
18 | "cordova-ios": ">=5.0.0"
19 | }
20 | }
21 | },
22 | "description": "A Google Firebase Crashlytics plugin",
23 | "repository": {
24 | "type": "git",
25 | "url": "https://github.com/ReallySmallSoftware/cordova-plugin-firebase-crashlytics.git"
26 | },
27 | "author": "Richard Windley (http://www.reallysmall.co.uk)",
28 | "license": "Apache-2.0",
29 | "bugs": {
30 | "url": "https://github.com/ReallySmallSoftware/cordova-plugin-firebase-crashlytics/issues"
31 | },
32 | "homepage": "https://github.com/ReallySmallSoftware/cordova-plugin-firebase-crashlytics",
33 | "keywords": [
34 | "ecosystem:cordova",
35 | "cordova-android",
36 | "cordova-ios",
37 | "cordova-browser"
38 | ],
39 | "dependencies": {
40 | "xcode": "^1.0.0"
41 | },
42 | "devDependencies": {
43 | "grunt": "^1.0.2",
44 | "grunt-contrib-jshint": "^1.1.0",
45 | "jshint-junit-reporter": "^0.2.3"
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/plugin.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Cordova Firebase Crashlytics Plugin
5 | Google Firebase Crashlytics
6 | MIT
7 | cloud, crash, reporting
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/src/android/uk/co/reallysmall/cordova/plugin/firebase/crashlytics/ActionHandler.java:
--------------------------------------------------------------------------------
1 | package uk.co.reallysmall.cordova.plugin.firebase.crashlytics;
2 |
3 | import org.apache.cordova.CallbackContext;
4 | import org.apache.cordova.CordovaInterface;
5 | import org.json.JSONArray;
6 |
7 | public interface ActionHandler {
8 | boolean handle(JSONArray args, CordovaInterface cordova, final CallbackContext callbackContext);
9 | }
10 |
--------------------------------------------------------------------------------
/src/android/uk/co/reallysmall/cordova/plugin/firebase/crashlytics/CrashHandler.java:
--------------------------------------------------------------------------------
1 | package uk.co.reallysmall.cordova.plugin.firebase.crashlytics;
2 |
3 | import com.google.firebase.crashlytics.FirebaseCrashlytics;
4 |
5 | import org.apache.cordova.CallbackContext;
6 | import org.apache.cordova.CordovaInterface;
7 | import org.json.JSONArray;
8 |
9 | public class CrashHandler implements ActionHandler {
10 | @Override
11 | public boolean handle(JSONArray args, CordovaInterface cordova, final CallbackContext callbackContext) {
12 |
13 | cordova.getActivity().runOnUiThread(new Runnable() {
14 | @Override
15 | public void run() {
16 | throw new RuntimeException();
17 | }
18 | });
19 |
20 | return true;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/android/uk/co/reallysmall/cordova/plugin/firebase/crashlytics/FirebaseCrashlyticsPlugin.java:
--------------------------------------------------------------------------------
1 | /**
2 | */
3 | package uk.co.reallysmall.cordova.plugin.firebase.crashlytics;
4 |
5 | import android.util.Log;
6 |
7 | import com.google.firebase.crashlytics.FirebaseCrashlytics;
8 |
9 | import org.apache.cordova.CallbackContext;
10 | import org.apache.cordova.CordovaInterface;
11 | import org.apache.cordova.CordovaPlugin;
12 | import org.apache.cordova.CordovaWebView;
13 | import org.json.JSONArray;
14 | import org.json.JSONException;
15 |
16 | import java.util.HashMap;
17 | import java.util.Map;
18 |
19 | public class FirebaseCrashlyticsPlugin extends CordovaPlugin {
20 | static final String TAG = "FBCrashlyticsPlugin";
21 | private Map handlers = new HashMap();
22 |
23 | public void initialize(CordovaInterface cordova, CordovaWebView webView) {
24 | super.initialize(cordova, webView);
25 |
26 | handlers.put("crash", new CrashHandler());
27 | handlers.put("logPriority", new LogPriorityHandler());
28 | handlers.put("log", new LogHandler());
29 | handlers.put("setString", new SetStringHandler());
30 | handlers.put("setBool", new SetBoolHandler());
31 | handlers.put("setDouble", new SetDoubleHandler());
32 | handlers.put("setFloat", new SetFloatHandler());
33 | handlers.put("setInt", new SetIntHandler());
34 | handlers.put("logException", new LogExceptionHandler());
35 | handlers.put("setUserIdentifier", new SetUserIdentifierHandler());
36 | handlers.put("logError", new LogErrorHandler());
37 | handlers.put("initialise", new InitialiseHandler());
38 |
39 | Log.d(TAG, "Initializing FBFirebaseCrashlyticsPlugin");
40 | }
41 |
42 | public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {
43 | Log.d(TAG, action);
44 |
45 | if (handlers.containsKey(action)) {
46 | return handlers.get(action).handle(args, this.cordova, callbackContext);
47 | }
48 |
49 | return false;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/android/uk/co/reallysmall/cordova/plugin/firebase/crashlytics/InitialiseHandler.java:
--------------------------------------------------------------------------------
1 | package uk.co.reallysmall.cordova.plugin.firebase.crashlytics;
2 |
3 | import com.google.firebase.crashlytics.FirebaseCrashlytics;
4 |
5 | import org.apache.cordova.CallbackContext;
6 | import org.apache.cordova.CordovaInterface;
7 | import org.json.JSONArray;
8 | import org.apache.cordova.PluginResult;
9 |
10 | public class InitialiseHandler implements ActionHandler {
11 | @Override
12 | public boolean handle(JSONArray args, CordovaInterface cordova, final CallbackContext callbackContext) {
13 |
14 | boolean result = false;
15 |
16 | if (FirebaseCrashlytics.getInstance().didCrashOnPreviousExecution()) {
17 | result = true;
18 | }
19 |
20 | callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result));
21 |
22 | return true;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/android/uk/co/reallysmall/cordova/plugin/firebase/crashlytics/LogErrorHandler.java:
--------------------------------------------------------------------------------
1 | package uk.co.reallysmall.cordova.plugin.firebase.crashlytics;
2 |
3 | import android.util.Log;
4 |
5 | import com.google.firebase.crashlytics.FirebaseCrashlytics;
6 |
7 | import org.apache.cordova.CallbackContext;
8 | import org.apache.cordova.CordovaInterface;
9 | import org.json.JSONArray;
10 | import org.json.JSONObject;
11 | import org.json.JSONException;
12 |
13 | public class LogErrorHandler implements ActionHandler {
14 | @Override
15 | public boolean handle(final JSONArray args, CordovaInterface cordova, final CallbackContext callbackContext) {
16 | cordova.getActivity().runOnUiThread(new Runnable() {
17 | @Override
18 | public void run() {
19 | JavascriptException exception = null;
20 |
21 | try {
22 | final String msg = args.getString(0);
23 | final JSONArray stl = args.getJSONArray(1);
24 | final StackTraceLine[] stackTraceLines = getStackTraceLines(stl);
25 |
26 | exception = new JavascriptException(msg, stackTraceLines);
27 | }
28 | catch(JSONException e) {
29 | Log.e(FirebaseCrashlyticsPlugin.TAG, "Unable to convert args to Exception object", e);
30 | }
31 |
32 | if(exception != null) {
33 | FirebaseCrashlytics.getInstance().recordException(exception);
34 | }
35 | }
36 | });
37 |
38 | return true;
39 | }
40 |
41 | private StackTraceLine[] getStackTraceLines(JSONArray array) throws JSONException {
42 | final int length = array.length();
43 |
44 | StackTraceLine[] stackTraceLines = new StackTraceLine[length];
45 | for(int i = 0; i < length; i ++) {
46 | JSONObject json = array.getJSONObject(i);
47 | stackTraceLines[i] = StackTraceLine.fromJSONObject(json);
48 | }
49 |
50 | return stackTraceLines;
51 | }
52 |
53 | private static class JavascriptException extends Exception {
54 | public JavascriptException(String message, StackTraceLine[] stackTraceLines) {
55 | super(message);
56 | StackTraceElement[] stackTrace = new StackTraceElement[stackTraceLines.length];
57 | for(int i = 0; i < stackTraceLines.length; i++) {
58 | stackTrace[i] = new StackTraceElement(
59 | stackTraceLines[i].className,
60 | stackTraceLines[i].functionName,
61 | stackTraceLines[i].fileName,
62 | stackTraceLines[i].lineNumber
63 | );
64 | }
65 |
66 | setStackTrace(stackTrace);
67 | }
68 | }
69 |
70 | private static class StackTraceLine {
71 | public String className;
72 | public String functionName;
73 | public String fileName;
74 | public int lineNumber;
75 |
76 | private StackTraceLine() {
77 | }
78 |
79 | public static StackTraceLine fromJSONObject(JSONObject json) throws JSONException {
80 | StackTraceLine sl = new StackTraceLine();
81 |
82 | sl.className = json.optString("className", "<>");
83 | sl.functionName = json.optString("functionName", "<>");
84 | sl.fileName = json.getString("fileName");
85 | sl.lineNumber = json.getInt("lineNumber");
86 |
87 | return sl;
88 | }
89 | }
90 | }
--------------------------------------------------------------------------------
/src/android/uk/co/reallysmall/cordova/plugin/firebase/crashlytics/LogExceptionHandler.java:
--------------------------------------------------------------------------------
1 | package uk.co.reallysmall.cordova.plugin.firebase.crashlytics;
2 |
3 | import android.util.Log;
4 |
5 | import com.google.firebase.crashlytics.FirebaseCrashlytics;
6 |
7 | import org.apache.cordova.CallbackContext;
8 | import org.apache.cordova.CordovaInterface;
9 | import org.json.JSONArray;
10 | import org.json.JSONException;
11 |
12 | public class LogExceptionHandler implements ActionHandler {
13 | @Override
14 | public boolean handle(final JSONArray args, CordovaInterface cordova, final CallbackContext callbackContext) {
15 | cordova.getActivity().runOnUiThread(new Runnable() {
16 | @Override
17 | public void run() {
18 | try {
19 | final String msg = args.getString(0);
20 |
21 | Exception exception = new Exception(msg);
22 |
23 | FirebaseCrashlytics.getInstance().recordException(exception);
24 | } catch (JSONException e) {
25 | Log.e(FirebaseCrashlyticsPlugin.TAG, "Error logging exception", e);
26 | }
27 | }
28 | });
29 |
30 | return true;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/android/uk/co/reallysmall/cordova/plugin/firebase/crashlytics/LogHandler.java:
--------------------------------------------------------------------------------
1 | package uk.co.reallysmall.cordova.plugin.firebase.crashlytics;
2 |
3 | import android.util.Log;
4 |
5 | import com.google.firebase.crashlytics.FirebaseCrashlytics;
6 |
7 | import org.apache.cordova.CallbackContext;
8 | import org.apache.cordova.CordovaInterface;
9 | import org.json.JSONArray;
10 | import org.json.JSONException;
11 |
12 | public class LogHandler implements ActionHandler {
13 | @Override
14 | public boolean handle(final JSONArray args, CordovaInterface cordova, final CallbackContext callbackContext) {
15 | cordova.getActivity().runOnUiThread(new Runnable() {
16 | @Override
17 | public void run() {
18 | try {
19 | final String msg = args.getString(0);
20 |
21 | FirebaseCrashlytics.getInstance().log(msg);
22 | } catch (JSONException e) {
23 | Log.e(FirebaseCrashlyticsPlugin.TAG, "Error logging", e);
24 | }
25 | }
26 | });
27 |
28 | return true;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/android/uk/co/reallysmall/cordova/plugin/firebase/crashlytics/LogPriorityHandler.java:
--------------------------------------------------------------------------------
1 | package uk.co.reallysmall.cordova.plugin.firebase.crashlytics;
2 |
3 | import android.util.Log;
4 |
5 | import com.google.firebase.crashlytics.FirebaseCrashlytics;
6 |
7 | import org.apache.cordova.CallbackContext;
8 | import org.apache.cordova.CordovaInterface;
9 | import org.json.JSONArray;
10 | import org.json.JSONException;
11 |
12 | public class LogPriorityHandler implements ActionHandler {
13 | @Override
14 | public boolean handle(final JSONArray args, CordovaInterface cordova, final CallbackContext callbackContext) {
15 | cordova.getActivity().runOnUiThread(new Runnable() {
16 | @Override
17 | public void run() {
18 | try {
19 | final Integer priority = args.getInt(0);
20 | final String tag = args.getString(1);
21 | final String msg = args.getString(2);
22 |
23 | FirebaseCrashlytics.getInstance().log(msg);
24 | } catch (JSONException e) {
25 | Log.e(FirebaseCrashlyticsPlugin.TAG, "Error logging with priority", e);
26 | }
27 | }
28 | });
29 |
30 | return true;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/android/uk/co/reallysmall/cordova/plugin/firebase/crashlytics/SetBoolHandler.java:
--------------------------------------------------------------------------------
1 | package uk.co.reallysmall.cordova.plugin.firebase.crashlytics;
2 |
3 | import android.util.Log;
4 |
5 | import com.google.firebase.crashlytics.FirebaseCrashlytics;
6 |
7 | import org.apache.cordova.CallbackContext;
8 | import org.apache.cordova.CordovaInterface;
9 | import org.json.JSONArray;
10 | import org.json.JSONException;
11 |
12 | public class SetBoolHandler implements ActionHandler {
13 | @Override
14 | public boolean handle(JSONArray args, CordovaInterface cordova, final CallbackContext callbackContext) {
15 | try {
16 | final String key = args.getString(0);
17 | final Boolean value = args.getBoolean(1);
18 |
19 | FirebaseCrashlytics.getInstance().setCustomKey(key, value);
20 | } catch (JSONException e) {
21 | Log.e(FirebaseCrashlyticsPlugin.TAG, "Error setting bool", e);
22 | }
23 | return true;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/android/uk/co/reallysmall/cordova/plugin/firebase/crashlytics/SetDoubleHandler.java:
--------------------------------------------------------------------------------
1 | package uk.co.reallysmall.cordova.plugin.firebase.crashlytics;
2 |
3 | import android.util.Log;
4 |
5 | import com.google.firebase.crashlytics.FirebaseCrashlytics;
6 |
7 | import org.apache.cordova.CallbackContext;
8 | import org.apache.cordova.CordovaInterface;
9 | import org.json.JSONArray;
10 | import org.json.JSONException;
11 |
12 | public class SetDoubleHandler implements ActionHandler {
13 | @Override
14 | public boolean handle(JSONArray args, CordovaInterface cordova, final CallbackContext callbackContext) {
15 | try {
16 | final String key = args.getString(0);
17 | final Double value = args.getDouble(1);
18 |
19 | FirebaseCrashlytics.getInstance().setCustomKey(key, value);
20 | } catch (JSONException e) {
21 | Log.e(FirebaseCrashlyticsPlugin.TAG, "Error setting double", e);
22 | }
23 | return true;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/android/uk/co/reallysmall/cordova/plugin/firebase/crashlytics/SetFloatHandler.java:
--------------------------------------------------------------------------------
1 | package uk.co.reallysmall.cordova.plugin.firebase.crashlytics;
2 |
3 | import android.util.Log;
4 |
5 | import com.google.firebase.crashlytics.FirebaseCrashlytics;
6 |
7 | import org.apache.cordova.CallbackContext;
8 | import org.apache.cordova.CordovaInterface;
9 | import org.json.JSONArray;
10 | import org.json.JSONException;
11 |
12 | public class SetFloatHandler implements ActionHandler {
13 | @Override
14 | public boolean handle(JSONArray args, CordovaInterface cordova, final CallbackContext callbackContext) {
15 | try {
16 | final String key = args.getString(0);
17 | final Double value = args.getDouble(1);
18 |
19 | FirebaseCrashlytics.getInstance().setCustomKey(key, value);
20 | } catch (JSONException e) {
21 | Log.e(FirebaseCrashlyticsPlugin.TAG, "Error setting float", e);
22 | }
23 | return true;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/android/uk/co/reallysmall/cordova/plugin/firebase/crashlytics/SetIntHandler.java:
--------------------------------------------------------------------------------
1 | package uk.co.reallysmall.cordova.plugin.firebase.crashlytics;
2 |
3 | import android.util.Log;
4 |
5 | import com.google.firebase.crashlytics.FirebaseCrashlytics;
6 |
7 | import org.apache.cordova.CallbackContext;
8 | import org.apache.cordova.CordovaInterface;
9 | import org.json.JSONArray;
10 | import org.json.JSONException;
11 |
12 | public class SetIntHandler implements ActionHandler {
13 | @Override
14 | public boolean handle(JSONArray args, CordovaInterface cordova, final CallbackContext callbackContext) {
15 | try {
16 | final String key = args.getString(0);
17 | final Integer value = args.getInt(1);
18 |
19 | FirebaseCrashlytics.getInstance().setCustomKey(key, value);
20 | } catch (JSONException e) {
21 | Log.e(FirebaseCrashlyticsPlugin.TAG, "Error setting int", e);
22 | }
23 | return true;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/android/uk/co/reallysmall/cordova/plugin/firebase/crashlytics/SetStringHandler.java:
--------------------------------------------------------------------------------
1 | package uk.co.reallysmall.cordova.plugin.firebase.crashlytics;
2 |
3 | import android.util.Log;
4 |
5 | import com.google.firebase.crashlytics.FirebaseCrashlytics;
6 |
7 | import org.apache.cordova.CallbackContext;
8 | import org.apache.cordova.CordovaInterface;
9 | import org.json.JSONArray;
10 | import org.json.JSONException;
11 |
12 | public class SetStringHandler implements ActionHandler {
13 | @Override
14 | public boolean handle(JSONArray args, CordovaInterface cordova, final CallbackContext callbackContext) {
15 |
16 | try {
17 | final String key = args.getString(0);
18 | final String value = args.getString(1);
19 |
20 | FirebaseCrashlytics.getInstance().setCustomKey(key, value);
21 | } catch (JSONException e) {
22 | Log.e(FirebaseCrashlyticsPlugin.TAG, "Error setting string", e);
23 | }
24 | return true;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/android/uk/co/reallysmall/cordova/plugin/firebase/crashlytics/SetUserIdentifierHandler.java:
--------------------------------------------------------------------------------
1 | package uk.co.reallysmall.cordova.plugin.firebase.crashlytics;
2 |
3 | import android.util.Log;
4 |
5 | import com.google.firebase.crashlytics.FirebaseCrashlytics;
6 |
7 | import org.apache.cordova.CallbackContext;
8 | import org.apache.cordova.CordovaInterface;
9 | import org.json.JSONArray;
10 | import org.json.JSONException;
11 |
12 | public class SetUserIdentifierHandler implements ActionHandler {
13 | @Override
14 | public boolean handle(JSONArray args, CordovaInterface cordova, final CallbackContext callbackContext) {
15 | try {
16 | final String identifier = args.getString(0);
17 |
18 | FirebaseCrashlytics.getInstance().setUserId(identifier);
19 | } catch (JSONException e) {
20 | Log.e(FirebaseCrashlyticsPlugin.TAG, "Error setting user identifier", e);
21 | }
22 | return true;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/ios/FirebaseCrashlyticsPlugin.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface FirebaseCrashlyticsPlugin : CDVPlugin
4 |
5 | - (void)crash:(CDVInvokedUrlCommand *)command;
6 | - (void)logPriority:(CDVInvokedUrlCommand *)command;
7 | - (void)logException:(CDVInvokedUrlCommand *)command;
8 | - (void)log:(CDVInvokedUrlCommand *)command;
9 | - (void)setString:(CDVInvokedUrlCommand *)command;
10 | - (void)setInt:(CDVInvokedUrlCommand *)command;
11 | - (void)setBool:(CDVInvokedUrlCommand *)command;
12 | - (void)setDouble:(CDVInvokedUrlCommand *)command;
13 | - (void)setFloat:(CDVInvokedUrlCommand *)command;
14 | - (void)setUserIdentifier:(CDVInvokedUrlCommand *)command;
15 | - (void)initialise:(CDVInvokedUrlCommand *)command;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/src/ios/FirebaseCrashlyticsPlugin.m:
--------------------------------------------------------------------------------
1 | #import "FirebaseCrashlyticsPlugin.h"
2 |
3 | #import
4 |
5 | #import
6 | @import FirebaseCrashlytics;
7 |
8 | @implementation FirebaseCrashlyticsPlugin
9 |
10 | - (void)pluginInitialize {
11 | if(![FIRApp defaultApp]) {
12 | [FIRApp configure];
13 | }
14 | }
15 |
16 | - (void)initialise:(CDVInvokedUrlCommand *)command {
17 | NSNumber *hasConsent = [command argumentAtIndex:0];
18 |
19 | NSNumber *result = [NSNumber numberWithInt:0];
20 |
21 | [[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:false];
22 |
23 | [[FIRCrashlytics crashlytics] checkForUnsentReportsWithCompletion:^(BOOL hasUnsentReports) {
24 |
25 | if (hasConsent && hasUnsentReports) {
26 | [[FIRCrashlytics crashlytics] sendUnsentReports];
27 | } else {
28 | [[FIRCrashlytics crashlytics] deleteUnsentReports];
29 | }
30 | }];
31 |
32 | if ([[FIRCrashlytics crashlytics] didCrashDuringPreviousExecution]) {
33 | result = [NSNumber numberWithInt:1];
34 | }
35 |
36 | CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:result];
37 |
38 | [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
39 | }
40 |
41 | - (void)crash:(CDVInvokedUrlCommand *)command {
42 | assert(NO);
43 | }
44 |
45 | - (void)logPriority:(CDVInvokedUrlCommand *)command {
46 | NSString *message = [command argumentAtIndex:2];
47 | [[FIRCrashlytics crashlytics] logWithFormat:@"%@", message];
48 | }
49 |
50 | - (void)logException:(CDVInvokedUrlCommand *)command {
51 | NSString *message = [command argumentAtIndex:0];
52 |
53 | NSDictionary *userInfo = @{
54 | NSLocalizedDescriptionKey: NSLocalizedString(@"Unexpected excerption", nil),
55 | NSLocalizedFailureReasonErrorKey: NSLocalizedString(message, nil),
56 | NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString(@"", nil)};
57 |
58 | NSError *error = [NSError errorWithDomain:@"uk.co.trssc" code:-1 userInfo:userInfo];
59 | [[FIRCrashlytics crashlytics] recordError:error];
60 |
61 | }
62 |
63 | - (void)log:(CDVInvokedUrlCommand *)command {
64 | NSString *message = [command argumentAtIndex:0];
65 | [[FIRCrashlytics crashlytics] logWithFormat:@"%@", message];
66 | }
67 |
68 | - (void)setString:(CDVInvokedUrlCommand *)command {
69 | NSString *key = [command argumentAtIndex:0];
70 | NSString *value = [command argumentAtIndex:1];
71 |
72 | [[FIRCrashlytics crashlytics] setCustomValue:value forKey:key];
73 | }
74 |
75 | - (void)setInt:(CDVInvokedUrlCommand *)command {
76 | NSString *key = [command argumentAtIndex:0];
77 | NSNumber *value = [command argumentAtIndex:1];
78 |
79 | [[FIRCrashlytics crashlytics] setCustomValue:value forKey:key];
80 | }
81 |
82 | - (void)setBool:(CDVInvokedUrlCommand *)command {
83 | NSString *key = [command argumentAtIndex:0];
84 | NSNumber *value = [command argumentAtIndex:1];
85 |
86 | [[FIRCrashlytics crashlytics] setCustomValue:value forKey:key];
87 | }
88 |
89 | - (void)setDouble:(CDVInvokedUrlCommand *)command {
90 | NSString *key = [command argumentAtIndex:0];
91 | NSNumber *value = [command argumentAtIndex:1];
92 |
93 | [[FIRCrashlytics crashlytics] setCustomValue:value forKey:key];
94 | }
95 |
96 | - (void)setFloat:(CDVInvokedUrlCommand *)command {
97 | NSString *key = [command argumentAtIndex:0];
98 | NSNumber *value = [command argumentAtIndex:1];
99 |
100 | [[FIRCrashlytics crashlytics] setCustomValue:value forKey:key];
101 | }
102 |
103 | - (void)setUserIdentifier:(CDVInvokedUrlCommand *)command {
104 | NSString *identifier = [command argumentAtIndex:0];
105 |
106 | [[FIRCrashlytics crashlytics] setUserID:identifier];
107 | }
108 |
109 | @end
110 |
111 |
--------------------------------------------------------------------------------
/types/index.d.ts:
--------------------------------------------------------------------------------
1 | declare namespace FirebaseCrashlytics {
2 | export function initialise(): FirebaseCrashlytics;
3 |
4 | export interface FirebaseCrashlytics {
5 |
6 | crash(): void;
7 | logPriority(priority: string, tag: string, message: string): void;
8 | log(message: string): void;
9 | logException(message: string): void;
10 | setString(key: string, value: string): void;
11 | setBool(key: string, value: boolean): void;
12 | setDouble(key: string, value: number): void;
13 | setFloat(key: string, value: number): void;
14 | setInt(key: string, value: number): void;
15 | setUserIdentifier(identifier: string): void;
16 | logError(message: string, stackTrace: StackTraceLine[]): void;
17 | initialise(hasConsent: boolean): Promise;
18 | }
19 |
20 | export interface StackTraceLine {
21 | className: string;
22 | functionName: string;
23 | fileName: string;
24 | lineNumber: number;
25 | }
26 | }
27 |
28 |
--------------------------------------------------------------------------------
/www/browser/crashlytics.js:
--------------------------------------------------------------------------------
1 | /*global alert */
2 | var PLUGIN_NAME = 'Crashlytics';
3 |
4 | function Crashlytics() {
5 | }
6 |
7 | Crashlytics.prototype = {
8 | initialise: function(hasConsent) {
9 | if (hasConsent) {
10 | console.log("Sending previous crash reports");
11 | }
12 |
13 | return Promise.resolve(false);
14 | },
15 | crash: function() {
16 | alert("Crash! Bang!");
17 | },
18 | logPriority: function(priority, tag, message) {
19 | console.debug("P: " + priority + " T: " + tag + " M: " + message);
20 | },
21 | log: function(message) {
22 | console.debug(message);
23 | },
24 | logException: function(message) {
25 | console.debug(message);
26 | },
27 | setString: function(key, value) {
28 | console.debug(key + ":" + value);
29 | },
30 | setBool: function(key, value) {
31 | console.debug(key + ":" + value);
32 | },
33 | setDouble: function(key, value) {
34 | console.debug(key + ":" + value);
35 | },
36 | setFloat: function(key, value) {
37 | console.debug(key + ":" + value);
38 | },
39 | setInt: function(key, value) {
40 | console.debug(key + ":" + value);
41 | },
42 | setUserIdentifier: function(identifier) {
43 | console.debug(identifier);
44 | }
45 | };
46 |
47 | // Log levels
48 | Crashlytics.LOG = {
49 | VERBOSE: 2,
50 | DEBUG: 3,
51 | INFO: 4,
52 | WARN: 5,
53 | ERROR: 6
54 | }
55 |
56 | // Backward compatibility instantiation
57 | Crashlytics.initialise = function() {
58 | return new Crashlytics();
59 | };
60 |
61 | module.exports = Crashlytics;
62 |
--------------------------------------------------------------------------------
/www/crashlytics.js:
--------------------------------------------------------------------------------
1 | var exec = require('cordova/exec');
2 |
3 | var PLUGIN_NAME = 'FirebaseCrashlytics';
4 |
5 | function Crashlytics() {
6 | }
7 |
8 | Crashlytics.prototype = {
9 | initialise: function(hasConsent) {
10 | return new Promise(function (resolve, reject) {
11 | exec(resolve, reject, PLUGIN_NAME, 'initialise', [hasConsent]);
12 | })
13 | },
14 | crash: function() {
15 | exec(null, null, PLUGIN_NAME, 'crash', []);
16 | },
17 | logPriority: function(priority, tag, message) {
18 | exec(null, null, PLUGIN_NAME, 'logPriority', [priority, tag, message]);
19 | },
20 | log: function(message) {
21 | exec(null, null, PLUGIN_NAME, 'log', [message]);
22 | },
23 | logException: function(message) {
24 | exec(null, null, PLUGIN_NAME, 'logException', [message]);
25 | },
26 | setString: function(key, value) {
27 | exec(null, null, PLUGIN_NAME, 'setString', [key, value]);
28 | },
29 | setBool: function(key, value) {
30 | exec(null, null, PLUGIN_NAME, 'setBool', [key, value]);
31 | },
32 | setDouble: function(key, value) {
33 | exec(null, null, PLUGIN_NAME, 'setDouble', [key, value]);
34 | },
35 | setFloat: function(key, value) {
36 | exec(null, null, PLUGIN_NAME, 'setFloat', [key, value]);
37 | },
38 | setInt: function(key, value) {
39 | exec(null, null, PLUGIN_NAME, 'setInt', [key, value]);
40 | },
41 | setUserIdentifier: function(identifier) {
42 | exec(null, null, PLUGIN_NAME, 'setUserIdentifier', [identifier]);
43 | },
44 | logError: function(message, stackTrace) {
45 | exec(null, null, PLUGIN_NAME, 'logError', [message, stackTrace]);
46 | },
47 | };
48 |
49 | // Log levels
50 | // See https://developer.android.com/reference/android/util/Log
51 | Crashlytics.LOG = {
52 | VERBOSE: 2,
53 | DEBUG: 3,
54 | INFO: 4,
55 | WARN: 5,
56 | ERROR: 6
57 | }
58 |
59 | // Backward compatibility instantiation
60 | Crashlytics.initialise = function() {
61 | return new Crashlytics();
62 | };
63 |
64 | module.exports = Crashlytics;
65 |
--------------------------------------------------------------------------------