Skip to content

Commit 58bd981

Browse files
authored
Add support for Crashlytics-triggered functions (#147)
1 parent 94a97e1 commit 58bd981

File tree

4 files changed

+201
-1
lines changed

4 files changed

+201
-1
lines changed

spec/index.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,4 @@ import './providers/firestore.spec';
4040
import './providers/https.spec';
4141
import './providers/pubsub.spec';
4242
import './providers/storage.spec';
43+
import './providers/crashlytics.spec';

spec/providers/crashlytics.spec.ts

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// The MIT License (MIT)
2+
//
3+
// Copyright (c) 2017 Firebase
4+
//
5+
// Permission is hereby granted, free of charge, to any person obtaining a copy
6+
// of this software and associated documentation files (the "Software"), to deal
7+
// in the Software without restriction, including without limitation the rights
8+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
// copies of the Software, and to permit persons to whom the Software is
10+
// furnished to do so, subject to the following conditions:
11+
//
12+
// The above copyright notice and this permission notice shall be included in all
13+
// copies or substantial portions of the Software.
14+
//
15+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
// SOFTWARE.
22+
23+
import * as crashlytics from '../../src/providers/crashlytics';
24+
import { config } from '../../src/index';
25+
import { apps as appsNamespace } from '../../src/apps';
26+
import { expect } from 'chai';
27+
import { fakeConfig } from '../support/helpers';
28+
29+
describe('Crashlytics Functions', () => {
30+
before(() => {
31+
config.singleton = fakeConfig();
32+
appsNamespace.init(config.singleton);
33+
process.env.GCLOUD_PROJECT = 'project1';
34+
});
35+
36+
after(() => {
37+
delete appsNamespace.singleton;
38+
delete config.singleton;
39+
delete process.env.GCLOUD_PROJECT;
40+
});
41+
42+
describe('#onNewDetected', () => {
43+
it('should return a TriggerDefinition with appropriate values', () => {
44+
const cloudFunction = crashlytics.issue().onNewDetected((event) => null);
45+
expect(cloudFunction.__trigger).to.deep.equal({
46+
eventTrigger: {
47+
eventType: 'providers/firebase.crashlytics/eventTypes/issue.new',
48+
resource: 'projects/project1',
49+
},
50+
});
51+
});
52+
});
53+
54+
describe('#onRegressed', () => {
55+
it('should return a TriggerDefinition with appropriate values', () => {
56+
const cloudFunction = crashlytics.issue().onRegressed((event) => null);
57+
expect(cloudFunction.__trigger).to.deep.equal({
58+
eventTrigger: {
59+
eventType: 'providers/firebase.crashlytics/eventTypes/issue.regressed',
60+
resource: 'projects/project1',
61+
},
62+
});
63+
});
64+
});
65+
66+
describe('#onVelocityAlert', () => {
67+
it('should return a TriggerDefinition with appropriate values', () => {
68+
const cloudFunction = crashlytics.issue().onVelocityAlert((event) => null);
69+
expect(cloudFunction.__trigger).to.deep.equal({
70+
eventTrigger: {
71+
eventType: 'providers/firebase.crashlytics/eventTypes/issue.velocityAlert',
72+
resource: 'projects/project1',
73+
},
74+
});
75+
});
76+
});
77+
});

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,13 @@
2323
// Providers:
2424
import * as analytics from './providers/analytics';
2525
import * as auth from './providers/auth';
26+
import * as crashlytics from './providers/crashlytics';
2627
import * as database from './providers/database';
2728
import * as firestore from './providers/firestore';
2829
import * as https from './providers/https';
2930
import * as pubsub from './providers/pubsub';
3031
import * as storage from './providers/storage';
31-
export { analytics, auth, database, firestore, https, pubsub, storage };
32+
export { analytics, auth, crashlytics, database, firestore, https, pubsub, storage };
3233

3334
// Exported root types:
3435
export * from './config';

src/providers/crashlytics.ts

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// The MIT License (MIT)
2+
//
3+
// Copyright (c) 2017 Firebase
4+
//
5+
// Permission is hereby granted, free of charge, to any person obtaining a copy
6+
// of this software and associated documentation files (the "Software"), to deal
7+
// in the Software without restriction, including without limitation the rights
8+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
// copies of the Software, and to permit persons to whom the Software is
10+
// furnished to do so, subject to the following conditions:
11+
//
12+
// The above copyright notice and this permission notice shall be included in all
13+
// copies or substantial portions of the Software.
14+
//
15+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
// SOFTWARE.
22+
23+
import { makeCloudFunction, CloudFunction, Event } from '../cloud-functions';
24+
25+
/** @internal */
26+
export const provider = 'firebase.crashlytics';
27+
28+
/**
29+
* Handle events related to Crashlytics issues. An issue in Crashlytics is an
30+
* aggregation of crashes which have a shared root cause.
31+
*/
32+
export function issue() {
33+
return new IssueBuilder('projects/' + process.env.GCLOUD_PROJECT);
34+
}
35+
36+
/** Builder used to create Cloud Functions for Crashlytics issue events. */
37+
export class IssueBuilder {
38+
/** @internal */
39+
constructor(private resource: string) { }
40+
41+
/** Handle Crashlytics New Issue events. */
42+
onNewDetected(handler: (event: Event<Issue>) => PromiseLike<any> | any
43+
): CloudFunction<Issue> {
44+
return makeCloudFunction({
45+
provider, handler,
46+
resource: this.resource,
47+
eventType: 'issue.new',
48+
});
49+
}
50+
51+
/** Handle Crashlytics Regressed Issue events. */
52+
onRegressed(handler: (event: Event<Issue>) => PromiseLike<any> | any
53+
): CloudFunction<Issue> {
54+
return makeCloudFunction({
55+
provider, handler,
56+
resource: this.resource,
57+
eventType: 'issue.regressed',
58+
});
59+
}
60+
61+
/** Handle Crashlytics Velocity Alert events. */
62+
onVelocityAlert(handler: (event: Event<Issue>) => PromiseLike<any> | any
63+
): CloudFunction<Issue> {
64+
return makeCloudFunction({
65+
provider, handler,
66+
resource: this.resource,
67+
eventType: 'issue.velocityAlert',
68+
});
69+
}
70+
}
71+
72+
/**
73+
* Interface representing a Crashlytics issue event that was logged for a specific issue.
74+
*/
75+
export class Issue {
76+
/** Fabric Issue ID. */
77+
issueId: string;
78+
79+
/** Issue title. */
80+
issueTitle: string;
81+
82+
/** App information. */
83+
appInfo: AppInfo;
84+
85+
/** When the issue was created (ISO8601 time stamp). */
86+
createTime: string;
87+
88+
/** When the issue was resolved, if the issue has been resolved (ISO8601 time stamp). */
89+
resolvedTime?: string;
90+
91+
/** Contains details about the velocity alert, if this event was triggered by a velocity alert. */
92+
velocityAlert?: VelocityAlert;
93+
}
94+
95+
export class VelocityAlert {
96+
/** The percentage of sessions which have been impacted by this issue. Example: .04 */
97+
crashPercentage: number;
98+
99+
/** The number of crashes that this issue has caused. */
100+
crashes: number;
101+
}
102+
103+
/**
104+
* Interface representing the application where this issue occurred.
105+
*/
106+
export interface AppInfo {
107+
/** The app's name. Example: "My Awesome App". */
108+
appName: string;
109+
110+
/** The app's platform. Examples: "android", "ios". */
111+
appPlatform: string;
112+
113+
/** Unique application identifier within an app store, either the Android package name or the iOS bundle id. */
114+
appId: string;
115+
116+
/**
117+
* The latest app version which is affected by the issue.
118+
* Examples: "1.0", "4.3.1.1.213361", "2.3 (1824253)", "v1.8b22p6".
119+
*/
120+
latestAppVersion: string;
121+
}

0 commit comments

Comments
 (0)