{"id":847,"date":"2020-08-11T09:29:48","date_gmt":"2020-08-11T00:29:48","guid":{"rendered":"https:\/\/www.typea.info\/blog\/?p=847"},"modified":"2020-10-31T00:11:19","modified_gmt":"2020-10-30T15:11:19","slug":"angular-cloud-functions","status":"publish","type":"post","link":"https:\/\/www.typea.info\/blog\/index.php\/2020\/08\/11\/angular-cloud-functions\/","title":{"rendered":"Angular \u304b\u3089 Cloud Functions \u3092\u547c\u3073\u51fa\u3059"},"content":{"rendered":"<p><a href=\"https:\/\/www.amazon.co.jp\/Angular%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E5%B1%B1%E7%94%B0-%E7%A5%A5%E5%AF%9B\/dp\/4774191302\/ref=as_li_ss_il?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&amp;dchild=1&amp;keywords=Angluar&amp;qid=1597105436&amp;sr=8-2&amp;linkCode=li2&amp;tag=typea09-22&amp;linkId=d24b79da801689478536205b0d16abc9&amp;language=ja_JP\" target=\"_blank\" rel=\"noopener noreferrer\"><img decoding=\"async\" src=\"\/\/ws-fe.amazon-adsystem.com\/widgets\/q?_encoding=UTF8&amp;ASIN=4774191302&amp;Format=_SL160_&amp;ID=AsinImage&amp;MarketPlace=JP&amp;ServiceVersion=20070822&amp;WS=1&amp;tag=typea09-22&amp;language=ja_JP\" border=\"0\"><\/a><img loading=\"lazy\" decoding=\"async\" style=\"margin: 0px !important; border: currentcolor !important; border-image: none !important;\" src=\"https:\/\/ir-jp.amazon-adsystem.com\/e\/ir?t=typea09-22&amp;language=ja_JP&amp;l=li2&amp;o=9&amp;a=4774191302\" alt=\"\" width=\"1\" height=\"1\" border=\"0\"><\/p>\n<h2>1.Cloud Functions \u30a2\u30d7\u30ea\u547c\u3073\u51fa\u3057<\/h2>\n<p>Web(Angular)\u3001\u30e2\u30d0\u30a4\u30eb(Flutter)\u30a2\u30d7\u30ea\u306e\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3068\u3057\u3066\u3001<a href=\"https:\/\/www.typea.info\/blog\/index.php\/category\/googleappengine\/\">GAE(SpringBoot)<\/a> \u3092\u4f7f\u304a\u3046\u3068\u601d\u3063\u3066\u3044\u305f\u306e\u3060\u304c\u3001<a href=\"https:\/\/www.typea.info\/blog\/index.php\/category\/google-cloud-functions\/\">Cloud Functions<\/a> \u3092\u4f7f\u3046\u3053\u3068\u3067\u3001\u5b9f\u88c5\u91cf\u306e\u524a\u6e1b\u304c\u51fa\u6765\u305d\u3046\u3068\u3082\u304f\u308d\u3093\u3067\u3001<\/p>\n<ul>\n<li><a href=\"https:\/\/www.typea.info\/blog\/index.php\/2020\/03\/17\/google-cloud-functinos\/\">\u8a66\u3059<\/a><\/li>\n<li><a href=\"https:\/\/www.typea.info\/blog\/index.php\/2020\/03\/22\/cloud_functions_for_firebase_dev_env\/\">\u74b0\u5883\u69cb\u7bc9<\/a><\/li>\n<li><a href=\"https:\/\/www.typea.info\/blog\/index.php\/2020\/03\/29\/cloud-functions-firestore-bind\/\">Firestore\u9023\u643a<\/a><\/li>\n<li><a href=\"https:\/\/www.typea.info\/blog\/index.php\/2020\/08\/02\/firebase-cli-google-cloud-functions\/\">\u30d5\u30a1\u30a4\u30eb\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9<\/a><\/li>\n<li><a href=\"https:\/\/www.typea.info\/blog\/index.php\/2020\/08\/09\/google-cloud-function-vision-api-ocr\/\">Cloud Vision\u9023\u643a<\/a><\/li>\n<\/ul>\n<p>\u307e\u3067\u9032\u3081\u3066\u304d\u305f\u3002<\/p>\n<p>\u57fa\u672c\u7684\u306b\u3001<a href=\"https:\/\/cloud.google.com\/functions\/docs\/tutorials\/http?hl=ja\">HTTP\u547c\u3073\u51fa\u3057\u306e\u30c1\u30e5\u30fc\u30c8\u30ea\u30a2\u30eb<\/a> \u3092\u30d9\u30fc\u30b9\u306b\u9032\u3081\u3066\u304d\u305f\u304c\u3001<\/p>\n<h3>1.1 HTTP\u30ea\u30af\u30a8\u30b9\u30c8\u547c\u3073\u51fa\u3057<\/h3>\n<p><a href=\"https:\/\/firebase.google.com\/docs\/functions\/http-events?hl=ja\">https:\/\/firebase.google.com\/docs\/functions\/http-events?hl=ja<\/a><\/p>\n<h3>1.2 \u30a2\u30d7\u30ea\u547c\u3073\u51fa\u3057<\/h3>\n<p>\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u30a2\u30d7\u30ea\u304b\u3089\u547c\u3073\u51fa\u3059\u5834\u5408\u3001\u30a2\u30d7\u30ea\u304b\u3089\u76f4\u63a5 Functions \u3092\u547c\u3073\u51fa\u3059\u3053\u3068\u304c\u3067\u304d\u308b<br \/>\n<a href=\"https:\/\/firebase.google.com\/docs\/functions\/callable?hl=ja\">https:\/\/firebase.google.com\/docs\/functions\/callable?hl=ja<\/a><\/p>\n<ul>\n<li>\u30a2\u30d7\u30ea\u304b\u3089\u95a2\u6570\u3092\u547c\u3073\u51fa\u3059\u306b\u306f\u3001Cloud Functions \u306b\u304a\u3044\u3066 HTTPS \u547c\u3073\u51fa\u3057\u53ef\u80fd\u95a2\u6570\u3092\u8a18\u8ff0\u3057\u3066\u30c7\u30d7\u30ed\u30a4\u3059\u308b\u3002<\/li>\n<li>\u30a2\u30d7\u30ea\u304b\u3089\u95a2\u6570\u3092\u547c\u3073\u51fa\u3059\u305f\u3081\u306e\u30af\u30e9\u30a4\u30a2\u30f3\u30c8 \u30ed\u30b8\u30c3\u30af\u3092\u8ffd\u52a0\u3059\u308b\u3002<\/li>\n<li>HTTPS \u547c\u3073\u51fa\u3057\u53ef\u80fd\u95a2\u6570\u306f HTTP \u95a2\u6570\u3068\u985e\u4f3c\u3057\u3066\u3044\u308b\u304c\u540c\u4e00\u3067\u306f\u306a\u3044\u3053\u3068\u306b\u6ce8\u610f\u3059\u308b\u3002<\/li>\n<li>HTTPS \u547c\u3073\u51fa\u3057\u53ef\u80fd\u95a2\u6570\u3092\u4f7f\u7528\u3059\u308b\u306b\u306f\u3001\u30d7\u30e9\u30c3\u30c8\u30d5\u30a9\u30fc\u30e0\u306e\u30af\u30e9\u30a4\u30a2\u30f3\u30c8 SDK \u3092 functions.https \u30d0\u30c3\u30af\u30a8\u30f3\u30c9 API \u3068\u3068\u3082\u306b\u4f7f\u7528\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u3002<\/li>\n<li>\u547c\u3073\u51fa\u3057\u53ef\u80fd\u95a2\u6570\u3067\u306f\u3001Firebase Authentication \u3068 FCM \u30c8\u30fc\u30af\u30f3\u304c\u4f7f\u7528\u53ef\u80fd\u306a\u5834\u5408\u3001\u81ea\u52d5\u7684\u306b\u30ea\u30af\u30a8\u30b9\u30c8\u306b\u8ffd\u52a0\u3055\u308c\u308b\u3002<\/li>\n<li>functions.https.onCall \u30c8\u30ea\u30ac\u30fc\u306f\u3001\u30ea\u30af\u30a8\u30b9\u30c8\u672c\u6587\u3092\u81ea\u52d5\u7684\u306b\u9006\u30b7\u30ea\u30a2\u30eb\u5316\u3057\u3001\u8a8d\u8a3c\u30c8\u30fc\u30af\u30f3\u3092\u691c\u8a3c\u3055\u308c\u308b\u3002<\/li>\n<\/ul>\n<h3>1.3 Angular Fire<\/h3>\n<p>\u3055\u3089\u306b\u3001Angular Fire\u3092\u5229\u7528\u3059\u308b\u3053\u3068\u3067\u3001Angular\u304b\u3089\u306e\u547c\u3073\u51fa\u3057\u304c\u7c21\u5358\u306b\u3002<br \/>\n<a href=\"https:\/\/github.com\/angular\/angularfire\/blob\/master\/docs\/functions\/functions.md\">https:\/\/github.com\/angular\/angularfire\/blob\/master\/docs\/functions\/functions.md<\/a><\/p>\n<h2>2.\u78ba\u8a8d\u624b\u9806<\/h2>\n<p><a href=\"https:\/\/github.com\/firebase\/quickstart-js\/blob\/2e56b835aa34d81bd71fcd3ca4d0999cd6d3789a\/functions\/functions\/index.js#L56-L103\">\u3053\u306e\u30b5\u30f3\u30d7\u30eb<\/a>\u3092\u53c2\u8003\u306b\u3001Firestore\u306b\u4fdd\u5b58\u3059\u308b\u3088\u3046\u306b\u66f8\u304d\u63db\u3048\u308b\u3002<\/p>\n<h3>2.1 Cloud Functions \u30b3\u30fc\u30c9<\/h3>\n<p>\u30b5\u30f3\u30d7\u30eb\u3069\u304a\u308a\u306b Promise \u3067\u66f8\u3044\u305f\u3089\u3001\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306b\u7d50\u679cJSON\u304cnull\u3067\u3082\u3069\u3063\u305f\u3002await async \u3067\u66f8\u304d\u76f4\u3057\u305f\u3089\u671f\u5f85\u3057\u305f\u7d50\u679c\u304c\u8fd4\u308b\u3088\u3046\u306b\u306a\u308b\u306b\u306f\u306a\u3063\u305f\u304c\u7406\u5c48\u306f\u4e0d\u660e\u3002<\/p>\n<p>context.auth \u306b\u8a8d\u8a3c\u60c5\u5831\u304c\u8a70\u3081\u3089\u308c\u3066\u304a\u308a\u3001\u4fbf\u5229\uff01<\/p>\n<h3>index.ts<\/h3>\n<pre class=\"prettyprint\">export const sampleOnCallAddMessge = functions.https.onCall( async (data, context) =&gt; {\n    const text:any = data?.text;\n\n    if (!(typeof text === 'string' || text.length === 0 )) {\n        throw new functions.https.HttpsError(\n            'invalid-argument','text is required.');\n    }\n    if (!context.auth) {\n        throw new functions.https.HttpsError(\n            'failed-precondition', 'not authenticated.');\n    }\n\n    const uid = context.auth.uid;\n    const name = context.auth.token.name || null;\n    const picture = context.auth.token.picture || null;\n    const email = context.auth.token.email || null;\n\n    try {\n        const result = await admin.firestore().collection(\"message\").add({\n            text: text,\n            author: {uid, name, picture, email}\n        });\n        return {result: `Message with ID: ${result.id} added.`};\n    } catch (error) {\n        throw new functions.https.HttpsError('unknown', error.message, error);\n    }\n});<\/pre>\n<h3>2.2 Angular \u30bd\u30fc\u30b9\u30b3\u30fc\u30c9<\/h3>\n<p>Angular Fire \u306e Functions\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u30a4\u30f3\u30dd\u30fc\u30c8<\/p>\n<p><a href=\"https:\/\/www.typea.info\/blog\/index.php\/2020\/04\/04\/firebase-hosting-firestore-release\/\">Angular Fire\u306e\u5c0e\u5165<\/a><\/p>\n<h3>app.module.ts<\/h3>\n<pre class=\"prettyprint\">import { AngularFireModule } from '@angular\/fire';\nimport { AngularFirestoreModule } from '@angular\/fire\/firestore';\nimport { AngularFireFunctionsModule, REGION } from '@angular\/fire\/functions';\n\nNgModule({\n  declarations: [\n    :\n  ],\n  imports: [\n      :&nbsp;&nbsp;&nbsp;&nbsp; \n    AngularFireModule.initializeApp(environment.firebase),\n    AngularFirestoreModule,\n    AngularFireFunctionsModule,\n  ],\n  providers: [\n    { provide: REGION, useValue: 'us-central1' }\n  ],\n    :\n})<\/pre>\n<h3>2.3 \u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8<\/h3>\n<ul>\n<li>\u30dc\u30bf\u30f3\u306a\u3069\u304b\u3089\u9069\u5f53\u306b\u3001addMessage()\u3092\u547c\u3073\u51fa\u3059\u3002<\/li>\n<\/ul>\n<p>&lt;button (click)=&#8221;addMessage()&#8221;&gt;Add Message&lt;\/button&gt;<\/p>\n<pre class=\"prettyprint\">import { Component, OnInit } from '@angular\/core';\nimport { AngularFireFunctions } from '@angular\/fire\/functions';\nimport { Observable } from 'rxjs';\n\n@Component({\n  selector: 'app-management',\n  templateUrl: '.\/management.component.html',\n  styleUrls: ['.\/management.component.scss']\n})\nexport class ManagementComponent implements OnInit {\n  addMessageCallable: any = null;\n\n  constructor(private fns: AngularFireFunctions) { \n    this.addMessageCallable = fns.httpsCallable('sampleOnCallAddMessge');\n  }\n\n  ngOnInit(): void {\n  }\n\n  addMessage() {\n    const obs = this.addMessageCallable({text:'this is function onCall sample'}) as Observable&lt;any&gt;;\n    console.log(obs);\n    obs.subscribe({\n      next(res) {\n        console.log(res);\n      },\n      error(err) {\n        console.log(err);\n      },\n      complete(){\n        console.log(\"COMPLETE\");\n      }\n    });\n    \n  }\n}<\/pre>\n<pre class=\"prettyprint\"><\/pre>\n<h2>3.\u5b9f\u884c<\/h2>\n<pre class=\"prettyprint\">Firestore\u306b\u4fdd\u5b58\u3055\u308c\u305f\uff01 OKOK<\/pre>\n<pre class=\"prettyprint\"><a href=\"https:\/\/www.typea.info\/blog\/wp-content\/uploads\/2020\/08\/gcp_storage_saved.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"gcp_storage_saved\" src=\"https:\/\/www.typea.info\/blog\/wp-content\/uploads\/2020\/08\/gcp_storage_saved_thumb.png\" alt=\"gcp_storage_saved\" width=\"398\" height=\"208\" border=\"0\"><\/a><\/pre>\n<pre class=\"prettyprint\">\u6b21\u306f\u3001\u30a2\u30d7\u30ea\u547c\u3073\u51fa\u3057\u3067\u3001\u30d5\u30a1\u30a4\u30eb\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3067\u304d\u308b\u304b\u306a\u3002\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>1.Cloud Functions \u30a2\u30d7\u30ea\u547c\u3073\u51fa\u3057 Web(Angular)\u3001\u30e2\u30d0\u30a4\u30eb(Flutter)\u30a2\u30d7\u30ea\u306e\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3068\u3057\u3066\u3001GAE(SpringBoot) \u3092\u4f7f\u304a\u3046\u3068\u601d\u3063\u3066\u3044\u305f\u306e\u3060\u304c\u3001Cloud Function [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":905,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"sns_share_botton_hide":"","vkExUnit_sns_title":"","_vk_print_noindex":"","sitemap_hide":"","_veu_custom_css":"","veu_display_promotion_alert":"","vkexunit_cta_each_option":"","footnotes":""},"categories":[102,104,112,100,1],"tags":[],"class_list":["post-847","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-angular","category-firebase","category-google-cloud-functions","category-google-cloud-platform","category-undefined"],"veu_head_title_object":{"title":"","add_site_title":""},"_links":{"self":[{"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/posts\/847","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=847"}],"version-history":[{"count":8,"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/posts\/847\/revisions"}],"predecessor-version":[{"id":932,"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/posts\/847\/revisions\/932"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/media\/905"}],"wp:attachment":[{"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=847"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=847"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=847"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}