Skip to content

Implement useEmulator for Functions #3906

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Oct 14, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/silver-books-reply.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'firebase': minor
'@firebase/functions-exp': minor
'@firebase/functions': minor
'@firebase/functions-types': minor
---

Add a useEmulator(host, port) method to Cloud Functions
18 changes: 18 additions & 0 deletions packages-exp/functions-exp/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
FunctionsService,
DEFAULT_REGION,
useFunctionsEmulator as _useFunctionsEmulator,
useEmulator as _useEmulator,
httpsCallable as _httpsCallable
} from './service';

Expand All @@ -55,6 +56,23 @@ export function getFunctions(
return functionsInstance;
}

/**
* Modify this instance to communicate with the Cloudd Functions emulator.
*
* <p> Note: this must be called before this instance has been used to do any operations.
*
* @param host the emulator host (ex: localhost)
* @param port the emulator port (ex: 5001)
* @public
*/
export function useEmulator(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it intended for the function to have the same name, useEmulator, in exp for Functions, Firestore, and Database? Sorry if I missed it in the proposal, I don't think I saw anything on it. This would require the user to rename it on import if they're planning to use more than one, correct? e.g.

import { useEmulator as useFunctionsEmulator } from 'firebase/functions'
import { useEmulator as useDatabaseEmulator } from 'firebase/database'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yeah the proposal didn't cover exp since I didn't know about that at the time. I see the issue. I could either:

a) Omit exp for now
b) Go with useFunctionsEmulator as I think that's reasonable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And actually now that I think about there's no reason to carry forward a @deprecated method to the exp API at all, right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh right, makes sense, much simpler.

functionsInstance: Functions,
host: string,
port: number
): void {
_useEmulator(functionsInstance as FunctionsService, host, port);
}

/**
* Changes this instance to point to a Cloud Functions emulator running
* locally. See https://firebase.google.com/docs/functions/local-emulator
Expand Down
24 changes: 21 additions & 3 deletions packages-exp/functions-exp/src/service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*/
import { assert } from 'chai';
import { createTestService } from '../test/utils';
import { FunctionsService, useFunctionsEmulator } from './service';
import { FunctionsService, useFunctionsEmulator, useEmulator } from './service';

describe('Firebase Functions > Service', () => {
describe('simple constructor', () => {
Expand All @@ -39,7 +39,7 @@ describe('Firebase Functions > Service', () => {
);
});

it('can use emulator', () => {
it('can use emulator (deprecated)', () => {
service = createTestService(app);
useFunctionsEmulator(service, 'http://localhost:5005');
assert.equal(
Expand All @@ -48,6 +48,15 @@ describe('Firebase Functions > Service', () => {
);
});

it('can use emulator', () => {
service = createTestService(app);
useEmulator(service, 'localhost', 5005);
assert.equal(
service._url('foo'),
'http://localhost:5005/my-project/us-central1/foo'
);
});

it('correctly sets region', () => {
service = createTestService(app, 'my-region');
assert.equal(
Expand All @@ -70,13 +79,22 @@ describe('Firebase Functions > Service', () => {
assert.equal(service._url('foo'), 'https://mydomain.com/foo');
});

it('prefers emulator to custom domain', () => {
it('prefers emulator to custom domain (deprecated)', () => {
const service = createTestService(app, 'https://mydomain.com');
useFunctionsEmulator(service, 'http://localhost:5005');
assert.equal(
service._url('foo'),
'http://localhost:5005/my-project/us-central1/foo'
);
});

it('prefers emulator to custom domain', () => {
const service = createTestService(app, 'https://mydomain.com');
useEmulator(service, 'localhost', 5005);
assert.equal(
service._url('foo'),
'http://localhost:5005/my-project/us-central1/foo'
);
});
});
});
18 changes: 18 additions & 0 deletions packages-exp/functions-exp/src/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,28 @@ export class FunctionsService implements _FirebaseService {
}
}

/**
* Modify this instance to communicate with the Cloudd Functions emulator.
*
* <p> Note: this must be called before this instance has been used to do any operations.
*
* @param host the emulator host (ex: localhost)
* @param port the emulator port (ex: 5001)
* @public
*/
export function useEmulator(
functionsInstance: FunctionsService,
host: string,
port: number
): void {
functionsInstance.emulatorOrigin = `http://${host}:${port}`;
}

/**
* Changes this instance to point to a Cloud Functions emulator running
* locally. See https://firebase.google.com/docs/functions/local-emulator
*
* @deprecated prefer the useEmulator(host, port) method.
* @param origin - The origin of the local emulator, such as
* "http://localhost:5005".
* @public
Expand Down
14 changes: 13 additions & 1 deletion packages/firebase/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1799,10 +1799,22 @@ declare namespace firebase.functions {
*/
export class Functions {
private constructor();

/**
* Modify this instance to communicate with the Cloudd Functions emulator.
*
* <p>Note: this must be called before this instance has been used to do any operations.
*
* @param host the emulator host (ex: localhost)
* @param port the emulator port (ex: 5001)
*/
useEmulator(host: string, port: number): void;

/**
* Changes this instance to point to a Cloud Functions emulator running
* locally. See https://firebase.google.com/docs/functions/local-emulator
*
*
* @deprecated prefer the useEmulator(host, port) method.
* @param origin The origin of the local emulator, such as
* "http://localhost:5005".
*/
Expand Down
11 changes: 11 additions & 0 deletions packages/functions-types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,21 @@ export class FirebaseFunctions {
*/
httpsCallable(name: string, options?: HttpsCallableOptions): HttpsCallable;

/**
* Modify this instance to communicate with the Cloudd Functions emulator.
*
* <p> Note: this must be called before this instance has been used to do any operations.
*
* @param host the emulator host (ex: localhost)
* @param port the emulator port (ex: 5001)
*/
useEmulator(host: string, port: number): void;

/**
* Changes this instance to point to a Cloud Functions emulator running
* locally. See https://firebase.google.com/docs/functions/local-emulator
*
* @deprecated prefer the useEmulator(host, port) method.
* @param origin The origin of the local emulator, such as
* "http://localhost:5005".
*/
Expand Down
13 changes: 13 additions & 0 deletions packages/functions/src/api/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,23 @@ export class Service implements FirebaseFunctions, FirebaseService {
return `https://${this.region}-${projectId}.cloudfunctions.net/${name}`;
}

/**
* Modify this instance to communicate with the Cloudd Functions emulator.
*
* <p>Note: this must be called before this instance has been used to do any operations.
*
* @param host the emulator host (ex: localhost)
* @param port the emulator port (ex: 5001)
*/
useEmulator(host: string, port: number): void {
this.emulatorOrigin = `http://${host}:${port}`;
}

/**
* Changes this instance to point to a Cloud Functions emulator running
* locally. See https://firebase.google.com/docs/functions/local-emulator
*
* @deprecated prefer the useEmulator(host, port) method.
* @param origin The origin of the local emulator, such as
* "http://localhost:5005".
*/
Expand Down
21 changes: 19 additions & 2 deletions packages/functions/test/service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,21 @@ describe('Firebase Functions > Service', () => {
);
});

it('can use emulator', () => {
it('can use emulator (deprecated)', () => {
service.useFunctionsEmulator('http://localhost:5005');
assert.equal(
service._url('foo'),
'http://localhost:5005/my-project/us-central1/foo'
);
});

it('can use emulator', () => {
service.useEmulator('localhost', 5005);
assert.equal(
service._url('foo'),
'http://localhost:5005/my-project/us-central1/foo'
);
});
});

describe('custom region/domain constructor', () => {
Expand All @@ -62,13 +70,22 @@ describe('Firebase Functions > Service', () => {
assert.equal(service._url('foo'), 'https://mydomain.com/foo');
});

it('prefers emulator to custom domain', () => {
it('prefers emulator to custom domain (deprecated)', () => {
const service = createTestService(app, 'https://mydomain.com');
service.useFunctionsEmulator('http://localhost:5005');
assert.equal(
service._url('foo'),
'http://localhost:5005/my-project/us-central1/foo'
);
});

it('prefers emulator to custom domain', () => {
const service = createTestService(app, 'https://mydomain.com');
service.useEmulator('localhost', 5005);
assert.equal(
service._url('foo'),
'http://localhost:5005/my-project/us-central1/foo'
);
});
});
});