Skip to content

Commit 78db0b8

Browse files
authored
Fix bug where v1 HTTP used v2 API if callback had len 1 (#955)
* Fix bug where v1 HTTP used v2 API if callback had len 1 * Changelog * Formatter
1 parent 4c33a76 commit 78db0b8

File tree

4 files changed

+34
-2
lines changed

4 files changed

+34
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Fix bug where the <data> arg of https onCall functions sometimes deviates from the documented format.

spec/v1/providers/https.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,28 @@ describe('#onCall', () => {
175175
};
176176
expect(cf.run(data, context)).to.deep.equal({ data, context });
177177
});
178+
179+
// Regression test for firebase-functions#947
180+
it('should lock to the v1 API even with function.length == 1', async () => {
181+
let gotData: Record<string, any>;
182+
const func = https.onCall((data) => {
183+
gotData = data;
184+
});
185+
186+
const req = new MockRequest(
187+
{
188+
data: { foo: 'bar' },
189+
},
190+
{
191+
'content-type': 'application/json',
192+
}
193+
);
194+
req.method = 'POST';
195+
196+
const response = await runHandler(func, req as any);
197+
expect(response.status).to.equal(200);
198+
expect(gotData).to.deep.equal({ foo: 'bar' });
199+
});
178200
});
179201

180202
describe('callable CORS', () => {

src/providers/https.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,12 @@ export function _onCallWithOptions(
7777
handler: (data: any, context: CallableContext) => any | Promise<any>,
7878
options: DeploymentOptions
7979
): HttpsFunction & Runnable<any> {
80-
const func: any = onCallHandler({ origin: true, methods: 'POST' }, handler);
80+
// onCallHandler sniffs the function length of the passed-in callback
81+
// and the user could have only tried to listen to data. Wrap their handler
82+
// in another handler to avoid accidentally triggering the v2 API
83+
const fixedLen = (data: any, context: CallableContext) =>
84+
handler(data, context);
85+
const func: any = onCallHandler({ origin: true, methods: 'POST' }, fixedLen);
8186

8287
func.__trigger = {
8388
labels: {},

src/v2/providers/https.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,11 @@ export function onCall<T = any, Return = any | Promise<any>>(
144144
}
145145

146146
const origin = 'cors' in opts ? opts.cors : true;
147-
const func: any = onCallHandler({ origin, methods: 'POST' }, handler);
147+
148+
// onCallHandler sniffs the function length to determine which API to present.
149+
// fix the length to prevent api versions from being mismatched.
150+
const fixedLen = (req: CallableRequest<T>) => handler(req);
151+
const func: any = onCallHandler({ origin, methods: 'POST' }, fixedLen);
148152

149153
Object.defineProperty(func, '__trigger', {
150154
get: () => {

0 commit comments

Comments
 (0)