Angular から Cloud Functions を呼び出す
1.Cloud Functions アプリ呼び出し
Web(Angular)、モバイル(Flutter)アプリのバックエンドとして、GAE(SpringBoot) を使おうと思っていたのだが、Cloud Functions を使うことで、実装量の削減が出来そうともくろんで、
まで進めてきた。
基本的に、HTTP呼び出しのチュートリアル をベースに進めてきたが、
1.1 HTTPリクエスト呼び出し
https://firebase.google.com/docs/functions/http-events?hl=ja
1.2 アプリ呼び出し
クライアントアプリから呼び出す場合、アプリから直接 Functions を呼び出すことができる
https://firebase.google.com/docs/functions/callable?hl=ja
- アプリから関数を呼び出すには、Cloud Functions において HTTPS 呼び出し可能関数を記述してデプロイする。
- アプリから関数を呼び出すためのクライアント ロジックを追加する。
- HTTPS 呼び出し可能関数は HTTP 関数と類似しているが同一ではないことに注意する。
- HTTPS 呼び出し可能関数を使用するには、プラットフォームのクライアント SDK を functions.https バックエンド API とともに使用する必要がある。
- 呼び出し可能関数では、Firebase Authentication と FCM トークンが使用可能な場合、自動的にリクエストに追加される。
- functions.https.onCall トリガーは、リクエスト本文を自動的に逆シリアル化し、認証トークンを検証される。
1.3 Angular Fire
さらに、Angular Fireを利用することで、Angularからの呼び出しが簡単に。
https://github.com/angular/angularfire/blob/master/docs/functions/functions.md
2.確認手順
このサンプルを参考に、Firestoreに保存するように書き換える。
2.1 Cloud Functions コード
サンプルどおりに Promise で書いたら、クライアントに結果JSONがnullでもどった。await async で書き直したら期待した結果が返るようになるにはなったが理屈は不明。
context.auth に認証情報が詰められており、便利!
index.ts
export const sampleOnCallAddMessge = functions.https.onCall( async (data, context) => { const text:any = data?.text; if (!(typeof text === 'string' || text.length === 0 )) { throw new functions.https.HttpsError( 'invalid-argument','text is required.'); } if (!context.auth) { throw new functions.https.HttpsError( 'failed-precondition', 'not authenticated.'); } const uid = context.auth.uid; const name = context.auth.token.name || null; const picture = context.auth.token.picture || null; const email = context.auth.token.email || null; try { const result = await admin.firestore().collection("message").add({ text: text, author: {uid, name, picture, email} }); return {result: `Message with ID: ${result.id} added.`}; } catch (error) { throw new functions.https.HttpsError('unknown', error.message, error); } });
2.2 Angular ソースコード
Angular Fire の Functionsモジュールをインポート
app.module.ts
import { AngularFireModule } from '@angular/fire'; import { AngularFirestoreModule } from '@angular/fire/firestore'; import { AngularFireFunctionsModule, REGION } from '@angular/fire/functions'; NgModule({ declarations: [ : ], imports: [ : AngularFireModule.initializeApp(environment.firebase), AngularFirestoreModule, AngularFireFunctionsModule, ], providers: [ { provide: REGION, useValue: 'us-central1' } ], : })
2.3 コンポーネント
- ボタンなどから適当に、addMessage()を呼び出す。
<button (click)=”addMessage()”>Add Message</button>
import { Component, OnInit } from '@angular/core'; import { AngularFireFunctions } from '@angular/fire/functions'; import { Observable } from 'rxjs'; @Component({ selector: 'app-management', templateUrl: './management.component.html', styleUrls: ['./management.component.scss'] }) export class ManagementComponent implements OnInit { addMessageCallable: any = null; constructor(private fns: AngularFireFunctions) { this.addMessageCallable = fns.httpsCallable('sampleOnCallAddMessge'); } ngOnInit(): void { } addMessage() { const obs = this.addMessageCallable({text:'this is function onCall sample'}) as Observable<any>; console.log(obs); obs.subscribe({ next(res) { console.log(res); }, error(err) { console.log(err); }, complete(){ console.log("COMPLETE"); } }); } }
3.実行
Firestoreに保存された! OKOK
次は、アプリ呼び出しで、ファイルアップロードできるかな。