Skip to content

Commit

Permalink
Merge pull request #64 from uraviOG/firebasecrashlytics
Browse files Browse the repository at this point in the history
FirebaseCrashlytics cloud function integration script
  • Loading branch information
faziletozer authored Jul 2, 2020
2 parents 407a7a9 + b3b4faf commit ea007cf
Show file tree
Hide file tree
Showing 7 changed files with 238 additions and 1 deletion.
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@ gradle-app.setting
.settings
Test.properties
uploadOptions.properties
version.old.properties
version.old.properties
**/node_modules/*
**/.firebase
**/.firebaserc
*/npm-debug.log
Binary file added firebaseCrashlytics/.DS_Store
Binary file not shown.
32 changes: 32 additions & 0 deletions firebaseCrashlytics/og-integration/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# OpsGenie Integration

Identify important conversion workflows in your app, so that when a issue is reported in that workflow via
Crashlytics, this issue will be sent to OpsGenie. This will allow you to react quicker to crashes that impact
important conversion workflows of your app.

Crashlytics is a crash reporter for Firebase.

Note: This assumes that you have Crashlytics in Firebase. [Learn more about Crashlytics](https://firebase.google.com/docs/crashlytics/)


## Setting up the sample

Create and setup the Firebase project:
1. Create a Firebase project using the [Firebase Developer Console](https://console.firebase.google.com).
1. Enable Billing on your Firebase the project by switching to the **Blaze** plan, this is currently needed to be able to perform HTTP requests to external services from a Cloud Function.
1.Include [Crashlytics in your project](https://firebase.google.com/docs/crashlytics/get-started).

Configuring the sample
1. Clone or download this repo and open the `firebaseCrashlytics/og-integration` directory.
1. You must have the Firebase CLI installed. If you don't have it, install it with `npm install -g firebase-tools` and then configure it with `firebase login`.
1. Configure the CLI locally by using `firebase use --add` and select your project in the list.
1. Install `npm` dependencies in the functions directory locally, by running: `cd functions; npm install;`

Integrating with OpsGenie
1. Configure the required environment variables for OpsGenie: `firebase functions:config:set og.webhookurl="<webhook url copied from OG firebaseCrashlytics integration>"`


## Deploy and test

1. Deploy your project using `firebase deploy`
1. Simulate a test crash. [Instructions](https://firebase.google.com/docs/crashlytics/force-a-crash)
1 change: 1 addition & 0 deletions firebaseCrashlytics/og-integration/firebase.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
122 changes: 122 additions & 0 deletions firebaseCrashlytics/og-integration/functions/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
{
"parserOptions": {
// Required for certain syntax usages
"ecmaVersion": 2017
},
"plugins": [
"promise"
],
"extends": "eslint:recommended",
"rules": {
// Removed rule "disallow the use of console" from recommended eslint rules
"no-console": "off",

// Removed rule "disallow multiple spaces in regular expressions" from recommended eslint rules
"no-regex-spaces": "off",

// Removed rule "disallow the use of debugger" from recommended eslint rules
"no-debugger": "off",

// Removed rule "disallow unused variables" from recommended eslint rules
"no-unused-vars": "off",

// Removed rule "disallow mixed spaces and tabs for indentation" from recommended eslint rules
"no-mixed-spaces-and-tabs": "off",

// Removed rule "disallow the use of undeclared variables unless mentioned in /*global */ comments" from recommended eslint rules
"no-undef": "off",

// Warn against template literal placeholder syntax in regular strings
"no-template-curly-in-string": 1,

// Warn if return statements do not either always or never specify values
"consistent-return": 1,

// Warn if no return statements in callbacks of array methods
"array-callback-return": 1,

// Requre the use of === and !==
"eqeqeq": 2,

// Disallow the use of alert, confirm, and prompt
"no-alert": 2,

// Disallow the use of arguments.caller or arguments.callee
"no-caller": 2,

// Disallow null comparisons without type-checking operators
"no-eq-null": 2,

// Disallow the use of eval()
"no-eval": 2,

// Warn against extending native types
"no-extend-native": 1,

// Warn against unnecessary calls to .bind()
"no-extra-bind": 1,

// Warn against unnecessary labels
"no-extra-label": 1,

// Disallow leading or trailing decimal points in numeric literals
"no-floating-decimal": 2,

// Warn against shorthand type conversions
"no-implicit-coercion": 1,

// Warn against function declarations and expressions inside loop statements
"no-loop-func": 1,

// Disallow new operators with the Function object
"no-new-func": 2,

// Warn against new operators with the String, Number, and Boolean objects
"no-new-wrappers": 1,

// Disallow throwing literals as exceptions
"no-throw-literal": 2,

// Require using Error objects as Promise rejection reasons
"prefer-promise-reject-errors": 2,

// Enforce “for” loop update clause moving the counter in the right direction
"for-direction": 2,

// Enforce return statements in getters
"getter-return": 2,

// Disallow await inside of loops
"no-await-in-loop": 2,

// Disallow comparing against -0
"no-compare-neg-zero": 2,

// Warn against catch clause parameters from shadowing variables in the outer scope
"no-catch-shadow": 1,

// Disallow identifiers from shadowing restricted names
"no-shadow-restricted-names": 2,

// Enforce return statements in callbacks of array methods
"callback-return": 2,

// Require error handling in callbacks
"handle-callback-err": 2,

// Warn against string concatenation with __dirname and __filename
"no-path-concat": 1,

// Prefer using arrow functions for callbacks
"prefer-arrow-callback": 1,

// Return inside each then() to create readable and reusable Promise chains.
"promise/always-return": 2,

//Enforces the use of catch() on un-returned promises
"promise/catch-or-return": 2,

// Warn against nested then() or catch() statements
"promise/no-nesting": 1
}
}
52 changes: 52 additions & 0 deletions firebaseCrashlytics/og-integration/functions/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
'use strict';

const functions = require('firebase-functions');
const rp = require('request-promise');

function createOgIssue(payload) {
const url = functions.config().og.webhookurl
console.log(`Calling webhook url ${url}`);
return rp({
method: 'POST',
uri: url,
body: payload,
json: true
});
}

function createCommonPayload(issue) {
const payload = {
issueId : issue.issueId,
issueTitle : issue.issueTitle,
appInfo : {
appName : issue.appInfo.appName,
appId : issue.appInfo.appId,
appPlatform : issue.appInfo.appPlatform,
latestAppVersion : issue.appInfo.latestAppVersion
}
};
return payload;
}

exports.createNewIssueOG = functions.crashlytics.issue().onNew(async (issue) => {
const payload = createCommonPayload(issue);
payload.issueType = "new";
await createOgIssue(payload);
console.log(`Sent new issue ${issue.issueId} details to OpsGenie`);
});

exports.createRegressedIssueOG = functions.crashlytics.issue().onRegressed(async (issue) => {
const payload = createCommonPayload(issue);
payload.issueType = "regressed";
await createOgIssue(payload);
console.log(`Sent regressed issue ${issue.issueId} details to OpsGenie`);
});

exports.createVelocityAlertOG = functions.crashlytics.issue().onVelocityAlert(async (issue) => {
const payload = createCommonPayload(issue);
payload.issueType = "velocity";
payload.crashCount = issue.velocityAlert.crashes;
payload.crashPercentage = issue.velocityAlert.crashPercentage;
await createOgIssue(payload);
console.log(`Created velocity issue ${issue.issueId} details in OpsGenie`);
});
26 changes: 26 additions & 0 deletions firebaseCrashlytics/og-integration/functions/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "og-issue-functions",
"description": "Cloud Functions for Firebase",
"dependencies": {
"request": "^2.88.2",
"request-promise": "^4.2.5",
"firebase-admin": "~8.9.2",
"firebase-functions": "^3.3.0"
},
"devDependencies": {
"eslint": "^6.8.0",
"eslint-plugin-promise": "^4.2.1"
},
"scripts": {
"lint": "./node_modules/.bin/eslint --max-warnings=0 .",
"serve": "firebase serve --only functions",
"shell": "firebase experimental:functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "8"
},
"private": true
}

0 comments on commit ea007cf

Please sign in to comment.