Skip to content

Commit 461e8bb

Browse files
author
Robert-Jan Huijsman
authored
Add a temporary shim to ignore spurious Storage events on function deployment. (#128)
Currently, running 'firebase deploy' will result in any Storage events triggering with a spurious (empty) event. This PR introduces a temporary shim in the SDK that will filter out such events, eliding the execution of the user's code. This shim is sub-optimal, as any filtered events still count as an execution for purposes of UX, but it'll avoid the drawbacks of executing user code with invalid input. This shim will be removed when the backend has stopped sending these spurious events.
1 parent 6aa18af commit 461e8bb

File tree

2 files changed

+53
-6
lines changed

2 files changed

+53
-6
lines changed

spec/providers/storage.spec.ts

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222

2323
import * as storage from '../../src/providers/storage';
2424
import { expect as expect } from 'chai';
25-
import {fakeConfig} from '../support/helpers';
26-
import {config} from '../../src/index';
25+
import { fakeConfig } from '../support/helpers';
26+
import { config } from '../../src/index';
2727

2828
describe('storage.FunctionBuilder', () => {
2929
before(() => {
@@ -55,7 +55,7 @@ describe('storage.FunctionBuilder', () => {
5555
});
5656
});
5757

58-
it ('should allow fully qualified bucket names', () => {
58+
it('should allow fully qualified bucket names', () => {
5959
let subjectQualified = new storage.ObjectBuilder('projects/_/buckets/bucky');
6060
let result = subjectQualified.onChange(() => null);
6161
expect(result.__trigger).to.deep.equal({
@@ -66,8 +66,43 @@ describe('storage.FunctionBuilder', () => {
6666
});
6767
});
6868

69-
it ('should throw with improperly formatted buckets', () => {
69+
it('should throw with improperly formatted buckets', () => {
7070
expect(() => storage.bucket('bad/bucket/format')).to.throw(Error);
7171
});
72+
73+
it('should filter out spurious deploy-time events', () => {
74+
let functionRan = false;
75+
let cloudFunction = storage.object().onChange(() => {
76+
functionRan = true;
77+
return null;
78+
});
79+
80+
let spuriousEvent = {
81+
timestamp: '2017-03-06T20:02:05.192Z',
82+
eventType: 'providers/cloud.storage/eventTypes/object.change',
83+
resource: 'projects/_/buckets/rjh-20170306.appspot.com/objects/#0',
84+
data: {
85+
kind: 'storage#object',
86+
resourceState: 'exists',
87+
id: 'rjh-20170306.appspot.com//0',
88+
selfLink: 'https://www.googleapis.com/storage/v1/b/rjh-20170306.appspot.com/o/',
89+
bucket: 'rjh-20170306.appspot.com',
90+
generation: '0',
91+
metageneration: '0',
92+
contentType: '',
93+
timeCreated: '1970-01-01T00:00:00.000Z',
94+
updated: '1970-01-01T00:00:00.000Z',
95+
size: '0',
96+
md5Hash: '',
97+
mediaLink: 'https://www.googleapis.com/storage/v1/b/rjh-20170306.appspot.com/o/?generation=0&alt=media',
98+
crc32c: 'AAAAAA==',
99+
},
100+
params: {},
101+
};
102+
return cloudFunction(spuriousEvent).then((result) => {
103+
expect(result).equals(null);
104+
expect(functionRan).equals(false);
105+
});
106+
});
72107
});
73108
});

src/providers/storage.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
// SOFTWARE.
2222

2323
import { Event, CloudFunction, makeCloudFunction } from '../cloud-functions';
24-
import {config} from '../index';
24+
import { config } from '../index';
2525

2626
/** @internal */
2727
export const provider = 'cloud.storage';
@@ -60,7 +60,19 @@ export class ObjectBuilder {
6060
* Handle any change to any object.
6161
*/
6262
onChange(handler: (event: Event<ObjectMetadata>) => PromiseLike<any> | any): CloudFunction<ObjectMetadata> {
63-
return makeCloudFunction({provider, handler, resource: this.resource, eventType: 'object.change'});
63+
// This is a temporary shim to filter out spurious events due to Functions deployments.
64+
// BUG(34123812): clean this up when backend fix for bug is deployed.
65+
let filterDeployEvents = (event: Event<ObjectMetadata>) => {
66+
if (event.data.timeCreated === '1970-01-01T00:00:00.000Z' && event.data.crc32c === 'AAAAAA==') {
67+
console.log(
68+
'Function triggered unneccessarily by Cloud Function deployment; function execution elided. ' +
69+
'This is a spurious event that will go away soon, sorry for the spam!');
70+
return null;
71+
}
72+
return handler(event);
73+
};
74+
return makeCloudFunction(
75+
{ provider, handler: filterDeployEvents, resource: this.resource, eventType: 'object.change' });
6476
}
6577
}
6678

0 commit comments

Comments
 (0)