-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
feat(functions): Adding AngularFireFunctions with httpCallable #1532
Changes from 3 commits
eebcee7
b43316f
d37e452
f20e7ae
727198e
a1247e1
8836de5
74664e6
8972403
a0a22c1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { NgModule } from '@angular/core'; | ||
import { AngularFireFunctions } from './functions'; | ||
import '@firebase/functions' | ||
|
||
@NgModule({ | ||
providers: [ AngularFireFunctions ] | ||
}) | ||
export class AngularFireFunctionsModule { } |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { ReflectiveInjector, Provider } from '@angular/core'; | ||
import { Observable } from 'rxjs/Observable' | ||
import { Subject } from 'rxjs/Subject' | ||
import { Observer } from 'rxjs/Observer'; | ||
import { TestBed, inject } from '@angular/core/testing'; | ||
import { _do } from 'rxjs/operator/do'; | ||
import { take } from 'rxjs/operator/take'; | ||
import { skip } from 'rxjs/operator/skip'; | ||
import { FirebaseApp, FirebaseAppConfig, AngularFireModule, FirebaseAppName } from 'angularfire2'; | ||
import { AngularFireFunctions, AngularFireFunctionsModule } from 'angularfire2/functions'; | ||
import { COMMON_CONFIG } from './test-config'; | ||
|
||
describe('AngularFireFunctions', () => { | ||
let app: FirebaseApp; | ||
let afFns: AngularFireFunctions; | ||
|
||
beforeEach(() => { | ||
TestBed.configureTestingModule({ | ||
imports: [ | ||
AngularFireModule.initializeApp(COMMON_CONFIG), | ||
AngularFireFunctionsModule | ||
] | ||
}); | ||
inject([FirebaseApp, AngularFireFunctions], (app_: FirebaseApp, _fn: AngularFireFunctions) => { | ||
app = app_; | ||
afFns = _fn; | ||
})(); | ||
}); | ||
|
||
afterEach(done => { | ||
app.delete().then(done, done.fail); | ||
}); | ||
|
||
it('should be exist', () => { | ||
expect(afFns instanceof AngularFireFunctions).toBe(true); | ||
}); | ||
|
||
it('should have the Firebase Functions instance', () => { | ||
expect(afFns.functions).toBeDefined(); | ||
}); | ||
|
||
}); | ||
|
||
const FIREBASE_APP_NAME_TOO = (Math.random() + 1).toString(36).substring(7); | ||
|
||
describe('AngularFireFunctions with different app', () => { | ||
let app: FirebaseApp; | ||
let afFns: AngularFireFunctions; | ||
|
||
beforeEach(() => { | ||
TestBed.configureTestingModule({ | ||
imports: [ | ||
AngularFireModule.initializeApp(COMMON_CONFIG), | ||
AngularFireFunctionsModule | ||
], | ||
providers: [ | ||
{ provide: FirebaseAppName, useValue: FIREBASE_APP_NAME_TOO }, | ||
{ provide: FirebaseAppConfig, useValue: COMMON_CONFIG } | ||
] | ||
}); | ||
inject([FirebaseApp, AngularFireFunctions], (app_: FirebaseApp, _fns: AngularFireFunctions) => { | ||
app = app_; | ||
afFns = _fns; | ||
})(); | ||
}); | ||
|
||
afterEach(done => { | ||
app.delete().then(done, done.fail); | ||
}); | ||
|
||
describe('<constructor>', () => { | ||
|
||
it('should be an AngularFireAuth type', () => { | ||
expect(afFns instanceof AngularFireFunctions).toEqual(true); | ||
}); | ||
|
||
}); | ||
|
||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { FirebaseFunctions, HttpsCallableResult } from '@firebase/functions-types'; | ||
import { FirebaseOptions } from '@firebase/app-types'; | ||
import { Injectable, Inject, Optional, NgZone } from '@angular/core'; | ||
import { Observable } from 'rxjs/Observable'; | ||
|
||
import { FirebaseAppConfig, FirebaseAppName, _firebaseAppFactory, FirebaseZoneScheduler } from 'angularfire2'; | ||
|
||
import 'rxjs/add/observable/fromPromise'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Make sure to use pipeable operators. |
||
import 'rxjs/add/operator/map' | ||
|
||
@Injectable() | ||
export class AngularFireFunctions { | ||
|
||
/** | ||
* Firebase Functions instance | ||
*/ | ||
public readonly functions: FirebaseFunctions; | ||
|
||
public readonly scheduler: FirebaseZoneScheduler; | ||
|
||
public httpsCallable<T, R>(name: string) { | ||
const callable = this.functions.httpsCallable(name); | ||
return (data: T) => { | ||
return this.scheduler.runOutsideAngular( | ||
Observable.fromPromise(callable(data)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use import { from } from 'rxjs/observable/from';
import { map } from 'rxjs/operators';
from(promise).pipe(
map(() => {})
); |
||
.map(r => r.data as R) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @davideast what do you think about mapping |
||
) | ||
} | ||
} | ||
|
||
constructor( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit. Bring the constructor above the method above. |
||
@Inject(FirebaseAppConfig) config:FirebaseOptions, | ||
@Optional() @Inject(FirebaseAppName) name:string, | ||
private zone: NgZone | ||
) { | ||
this.scheduler = new FirebaseZoneScheduler(zone); | ||
|
||
this.functions = zone.runOutsideAngular(() => { | ||
const app = _firebaseAppFactory(config, name); | ||
return app.functions(); | ||
}); | ||
|
||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
import './functions.spec'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './public_api'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
{ | ||
"name": "angularfire2/functions", | ||
"version": "ANGULARFIRE2_VERSION", | ||
"description": "The functions module", | ||
"main": "../bundles/functions.umd.js", | ||
"module": "index.js", | ||
"es2015": "./es2015/index.js", | ||
"keywords": [ | ||
"angular", | ||
"firebase", | ||
"rxjs" | ||
], | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/angular/angularfire2.git" | ||
}, | ||
"author": "angular,firebase", | ||
"license": "MIT", | ||
"peerDependencies": { | ||
"angularfire2": "ANGULARFIRE2_VERSION", | ||
"@angular/common": "ANGULAR_VERSION", | ||
"@angular/core": "ANGULAR_VERSION", | ||
"@angular/platform-browser": "ANGULAR_VERSION", | ||
"@angular/platform-browser-dynamic": "ANGULAR_VERSION", | ||
"@firebase/app": "FIREBASE_APP_VERSION", | ||
"@firebase/functions": "FIREBASE_FUNCTIONS_VERSION", | ||
"rxjs": "RXJS_VERSION", | ||
"zone.js": "ZONEJS_VERSION" | ||
}, | ||
"typings": "index.d.ts" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './functions'; | ||
export * from './functions.module'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
|
||
export const COMMON_CONFIG = { | ||
apiKey: "AIzaSyBVSy3YpkVGiKXbbxeK0qBnu3-MNZ9UIjA", | ||
authDomain: "angularfire2-test.firebaseapp.com", | ||
databaseURL: "https://angularfire2-test.firebaseio.com", | ||
storageBucket: "angularfire2-test.appspot.com", | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
{ | ||
"compilerOptions": { | ||
"baseUrl": ".", | ||
"experimentalDecorators": true, | ||
"emitDecoratorMetadata": true, | ||
"module": "es2015", | ||
"target": "es2015", | ||
"noImplicitAny": false, | ||
"outDir": "../../dist/packages-dist/functions/es2015", | ||
"rootDir": ".", | ||
"sourceMap": true, | ||
"inlineSources": true, | ||
"declaration": false, | ||
"removeComments": true, | ||
"strictNullChecks": true, | ||
"lib": ["es2015", "dom", "es2015.promise", "es2015.collection", "es2015.iterable"], | ||
"skipLibCheck": true, | ||
"moduleResolution": "node", | ||
"paths": { | ||
"angularfire2": ["../../dist/packages-dist"] | ||
} | ||
}, | ||
"files": [ | ||
"index.ts", | ||
"../../node_modules/zone.js/dist/zone.js.d.ts" | ||
], | ||
"angularCompilerOptions": { | ||
"skipTemplateCodegen": true, | ||
"strictMetadataEmit": true, | ||
"enableSummariesForJit": false | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"extends": "./tsconfig-build.json", | ||
"compilerOptions": { | ||
"target": "es5", | ||
"outDir": "../../dist/packages-dist/functions", | ||
"declaration": true | ||
}, | ||
"files": [ | ||
"public_api.ts", | ||
"../../node_modules/zone.js/dist/zone.js.d.ts" | ||
], | ||
"angularCompilerOptions": { | ||
"skipTemplateCodegen": true, | ||
"strictMetadataEmit": true, | ||
"enableSummariesForJit": false, | ||
"flatModuleOutFile": "index.js", | ||
"flatModuleId": "angularfire2/functions" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"extends": "./tsconfig-esm.json", | ||
"compilerOptions": { | ||
"baseUrl": ".", | ||
"paths": { | ||
"angularfire2": ["../../dist/packages-dist"], | ||
"angularfire2/functions": ["../../dist/packages-dist/functions"] | ||
} | ||
}, | ||
"files": [ | ||
"index.spec.ts", | ||
"../../node_modules/zone.js/dist/zone.js.d.ts" | ||
] | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can now just do
import { Observable } from 'rxjs';