ラベル Firebase Hosting の投稿を表示しています。 すべての投稿を表示
ラベル Firebase Hosting の投稿を表示しています。 すべての投稿を表示

2022/05/17

vsReversiアップデート

GCPのデモとして用意していた vsReversiをアップデートしました。


アップデート内容は以下のとおりです。

  • ユーザのログインと新規登録を別に
  • SPA対応
  • デザイン変更

ユーザのログインと新規登録を別に

ユーザ認証にはGCPのIdentity Platform(Firebase Authentication)を使用していますが、これには出来合いのUIとして提供されるもの(Firebase UI)も、単体のAPIも、ログインと新規登録の区別がありません。それらが一緒になったサインインがあるのみです。

しかし日本では、ユーザ登録と登録済みユーザのログインが別になっているのをよく見るので、それらしく分けてみました。やってみて出来なくはないのですが、かえって実装は面倒になってしまった印象です。

またEメールで登録する場合は、OAuth(Google/Facebook/Twitter/etc.)に比べて、追加で実装しなければならないのものが多いので、余計面倒です。具体的には、

  • 入力されたEメールアドレスを確認する
  • 入力されたEメールアドレスが間違っていた場合にユーザ登録を解除
  • ユーザがパスワードを忘れた場合のパスワードリセット
  • ユーザがEメールアドレスの変更を希望した場合の対処 (vsReversiでは割愛)
  • さらにこれらのUIのカスタマイズ (vsReversiでは割愛)

Firebase UIではこれらの一部が対応済みなので、簡単に実装したいならそれを使うのが楽です。ただしUIのデザインは簡素なものなので、カスタマイズしたくなります。


SPA対応

Angularを使って一部のページをSingle Page Applicationに対応させました。ログイン/新規登録後のページがそれです。マテリアルデザインは採用していないので それっぽい見た目にはなっていないのですが、ページ遷移が速くなりました。

今までGAE/Java8メインで作っていたのですが、「GAE/Java8でSPA対応に苦戦」に記載したように、これは複数のURIに1つのページを割り当てることができないので、実装の変更が大掛かりになりました。具体的には...

  • HTMLなどスタティックコンテンツをFirebase Hostingに移行してURI割り当てを解決。
  • ajaxリクエストエンドポイントは過去のGAEの実装を流用。ただしCORS(Cross Origin Resource Sharing)に対応。
  • 管理者用のページはCloud Runで管理者の認証を実装。


GCPの初期からあるサービスだけに、GAEは単体でいろいろ必要なものが用意されていることを実感できました。今回は対応できないものが見つかったので、他にいろいろと物色することになりました。それぞれが別のサービスとして名前を持っているので、利用したサービスの数が増えています。


デザイン変更

SPA対応のついでですが、見た目だけの変更です。


CPUの思考ルーチンなどその他は以前のままで、変りありません。


2022/04/23

GAE/Java8でSPA対応に苦戦

GAEの第1世代VMであるJava8とGoで動かしているアプリを、Single Page Application(以下 略称のSPAを使用します)に一部作り直そうと検討しているのですが、意外と苦戦しています。


問題

SPAでは、複数のパスを実際には1つのHTML/JavaScriptで表示します。例として、以下のパスの3ページを用意したとします。

/         ←3つとも/index/htmlが対応

/aaa    ←〃

/bbb    ←

見た目には3ページでも、実際にはJavaScriptでリクエストされたパスを見て表示内容を切り替えているだけで、コンテンツとしてはこれら3ページを1つのHTML/JavaScriptが表示します。


で、これらのページをいつものようにGAEの静的ファイルとしてホストしようと思っていました。しかしGAEの静的ファイルは基本的に1パス=1ファイルに対応します。つまり"/"に対応するHTML/JavaScriptで3ページすべてを表示するつくりにすると、残り2ページをリクエストしてもGAEの静的ファイルサーバが「404 Not found」を返してしまい、HTML/JavaScriptが得られません。

Java8以外だとapp.yamlの記述(参照:ハンドラ要素)で、"/aaa", "/bbb"が指定された場合でも"/"と同じコンテンツを返すことが可能です。しかしJava8では、そもそもapp.yamlが使用できません。

サーバサイドのアプリはすでに作成済みのものを使いまわすつもりなので、今更ほかの言語で書き換える気などありません。このアプリではMemcacheやSearch APIなど第1世代VMでしか提供されない機能を利用していますので、使えるのは第1世代VMに縛られます。


解決案

いろいろ調査・検討してみました。ここから先はアイデアだけで試したわけではありません。


A案. Firebase Hostingへの一部移行

静的ファイルのホストをFirebase Hostingに変えます。複数パスが1つのHTML/JavaScriptに対応する問題は、firebase.jsonのリライト設定(参照:リライトを構成する)で解決できそうです。

Firebase Hostingは独自ドメインにも対応しています。GAEで実装したAPIはFirebase Hostingとは別ドメインになりますので、Cross Origin Resource Sharing(以下CORS)ポリシーに触れますが、どちらも自前で実装するので適切にレスポンスを返すだけです。


しかし実際のアプリには前記の3つのパス以外に、SPAに入らない全く独立したページも存在します。以下のような感じです。

/         ←3つとも/index/htmlが対応

/aaa    ←

/bbb    ←

/ccc/xxx    ←独立した動的ページ

この独立ページ"/ccc/xxx"は静的ファイルではありませんので、Firebase Hostingで対応できません。現状は静的ファイルと一緒にGAEで対応していますが、Firebase HostingとGAEでドメインが異なるのは問題です。アドレスはエンドユーザにも見えますので、同じアプリの一部であること、あやしいページに遷移したわけではないことがエンドユーザにもわかるように同じドメインへの配置が必要です。


B案. 動的ページは空コンテンツを用意

前記の独立した動的ページ"/ccc"にはhtml/body要素のみの空ページを用意しておき、"/xxx"の部分は前記のリライトで"/ccc"に置き換えます。中身はajaxで"/xxx"を判断して埋めます。

これならエンドユーザに見えるドメインはすべて同じにできます。ajaxのリスエストエンドポイントはGAEなので別ドメインですが、エンドユーザには見えないので問題にならないはずです。

ただしこのページは他のページとデザインなども異なるので、「空ページを埋める」でどこまで対応できるのか不安が残ります。


C案. API Gatewayで振り分け

一般提供になったばかり(だったと思う)API Gatewayで同じドメインの別パスとして、Firebase HostingとGAEの振り分けを追加する案です。B案の動的ページの不安も解決できる可能性があります。

しかしドキュメントを読んだだけでも以下の懸念が...

API GatewayがFirebase HostingやCloud Storageの静的コンテンツも対象に出来れば面白いと思うのですが。1つのWebアプリとして単一のドメインの中で静的コンテンツやajaxのAPIだけでなく、公開APIも対応できます。

API Gatewayのドキュメントには静的コンテンツに関する記述はなさそうです。名前のとおりWeb APIのみを対象としているのかもしれません。


(2022/4/25追記)

Firebase Hostingの動的コンテンツ配信の機能(参照:Firebase Hosting を使用した動的コンテンツの配信とマイクロサービスのホスティング)がGAEにも対応していれば問題ないのですが、この機能はCloud Functions for FirebaseとCloud Runにしか対応していません。

仮にアプリを書き直すにしてもCloud Functions for FirebaseはJavaScript/TypeScriptにしか対応していないようなのでパフォーマンスとランニングコストに疑問がありますし、Cloud Runでもランニングコストが課題になります。

なかなか、かゆいところに手が届いてくれないですね。

2022/03/26

Firebase Hostingで設定したカスタムドメインを解除してみた

  HTML/CSS/JavaScriptや、画像/動画/音声などのメディアコンテンツのみで構成されたwebサイトを構築するなら、Firebase Hostingを使用するという手段が用意されています。Firebase Hostingでwebサイトを作るとデフォルトのドメインが割り当てられるので、コンテンツさえ作ればすぐにwebサイトの運用が可能になります。デプロイしたコンテンツはCDNにも登録されるので、ユーザはアクセスが快適という特徴があります。

 Firebase Hostingでもカスタムドメインでwebサイトを公開することが可能です。その手順は「カスタムドメインを接続する」に書かれているとおりで、Firebaseのコンソールから簡単にできます。


 今回の記事は、Firebase Hostingで公開したサイトに一度接続したカスタムドメインを、解除してみたときの体験です。


ダッシュボードが行方不明

 まず最初に遭遇したのが「Firebase Hostingのダッシュボードがどこにあるのかわからなくなった」という問題。カスタムドメインの接続を試したときは、手順どおりで以下のキャプチャの様なダッシュボードを表示できていました。(このキャプチャはカスタムドメインに未接続です)


 その後日、試したカスタムドメインを解除しようと思い、同じリンクをたどったのですが、今度は以前の様なダッシュボードが表示されません。以下のキャプチャの様にFirebase Hostingの開始の案内が表示されます。先日設定したサイトはどうなったの?


 実はこのページは、シングルページで開始の案内からダッシュボードまで同じURIで実装されています。そしてフラグメントにも対応していないので、開始の案内もダッシュボードも全く同じURIとなります。
 ダッシュボードにたどり着くには、ページを表示する度に以下の手順を踏む必要がありました。

  1. 「始める」ボタンを押す。
  2. 「Firebase Hostingの設定」は説明だけなのでどんどん進めて、
  3. 「Firebase Hostingへのデプロイ」にある「コンソールに進む」を押す。

  4. めでたくFirebase Hostingのダッシュボードが表示される。

 開始の案内や手順の説明は1回でいいと思うのですが、毎回これらを見なければならない実装はいかがなものでしょう。ちなみに言語を英語に変えても同様です。「始める」ボタンを押すと「Firebase Hostingの設定」が右からフェードインして来るので、シングルページだと分かるだろうという思い込みで作られているようですが、このアニメーションを見ていなければ理解できません。シングルページアプリケーションは昨今のトレンドですが、このページの作りはトラップですね。

 ここまで来ると、カスタムドメインのメニューからドメイン編集/削除を選べるようになります。

 ダッシュボードの表示方法がわからなくてFirebaseのサポートに英語で質問したのですが、自分で見つけてしまいました。ついでにサポートに確認したところ「この手順でいい」みたいな返事があったので、手順は間違っていないはずです。


(2022/05/4追記)

ダッシュボードはFirebase Hostingのアプリがあればデフォルトで表示されました。この「ダッシュボードが行方不明」に気付いたのは、一度作成したFirebase Hostingアプリを削除した後でしたので、気付きませんでした。


謎のアクセス

 やっとカスタムドメインの設定を解除し、そのドメインにはGAEアプリのURIを設定しなおしました。しばらくしてGAEアプリのプロジェクトのCloud Loggingに、以下のようなログが残っていることに気付きました。


 リクエストされているパスは以下のとおり。15分間隔で2回ずつ、1日中アクセスが続きます。

/.well-known/acme-challenge/XXXXXXXXXXXXXXXXXXX

 もちろん自分でこんなアクセスした覚えはありません。というかユーザエージェントとして「Google-Firebase...」って。


 これについてFirebaseのサポートに確認したところ、「すでにカスタムドメインの解除は行われていて、このリクエストはそのうち停止する」との回答がありました。Firebase Hostingがこのアクセスを行っている理由は「カスタムドメインの接続先を変えたりした場合に、新しいSSL証明書が再プロビジョニングされるのを待ったり、証明書の作成プロセス全体を再度実行したりしなくていいように」とのことでした。

 上記のアクセスが実際に停止したのは、カスタムドメインの設定を解除してから4週間後でした。けっこう長いです。

2021/08/07

サブドメインでのGAEアプリ運用

 独自ドメインのサブドメインでGAEアプリを運用する場合について調査したときの、忘備録です。


Google提供のサービスのみでの実現

当初LotteryServは以下の様なY's Software Atelierのサブドメインでの運用を考えていました。


Y's Software Atelier

ドメイン : ys-software-atelier.biz
実体は下記とは違うGAEアプリ、この独自ドメインはGoogle Domainsで取得。

LotteryServ

サブドメイン : lotteryserv.ys-software-atelier.biz
実体はGAEアプリLotteryServ、上記ドメインのサブドメインにしたい。


いきなり結論ですが、このような構成はGoogleから提供されるサービスのみでは出来ないようです。理由はこちらのGoogle DNSのドキュメント「重複するゾーン」の以下の制限です。

重複する一般公開ゾーン同士は、同じ Cloud DNS ネームサーバー上に存在できません。

メインドメイン/サブドメイン共にGAEアプリであり、どちらもドメイン名をGoogle DNSで割り当てようとしているので、上記の制限に該当します。最初から無理でした。他にも複数のサブドメインで複数のGAEアプリを運用するケースも該当しますね。

解決策

この状況を解決しようと思えば、以下の方法があるようです。どちらも私が試したわけではなく、調査のみですが。

Firebase Hostingを併用する

Googleの提供するDNSサービスはGoogle DNSの他にFirebase Hostingもあります。片方をこれに替えれば解決できそうです。
ただしFirebase Hostingを利用するには、スタティックなwebコンテンツのみの実装にする必要があります。コンテンツに動的に動作/表示を変えたい部分があれば、そこはajaxとFirebase Realtime Datebase/Firestore/Cloud Functionsあたりを使用することになると思います。

Google以外のDNSサービスを併用する

Google以外のサービスも併用すればサブドメインでの運用も実現できるようです。これに挑戦した方の記事としては以下が見つかりました。
どちらも独自ドメインをお名前.comで取得しているので、サブドメインはお名前.comのDNSサービスで実現しています。
お名前.comでなくても、MyDNS.JPでも解決できると思われます。MyDNS.JPは無料で利用できるのが利点ですが、1週間ごとに利用の通知が必要です。これはCloud SchedulerとGAEで簡単に実現できますが。

2021/07/29

ログイン/再認証時のドメイン表示について

LotteryServに Eメールアドレス/パスワード以外の方法でログインまたは再認証するとき、以下の画面キャプチャの様にLotteryServではないドメインが表示されます。これは不具合ではなく、正常な動作ですのでご安心ください。



以下、このような表示になる原因について説明します。技術的な内容ですので、興味のある方だけ読んでいただければ十分です。


LotteryServは主にGCPの中の1サービスであるGAEを使って実装していますので、独自ドメインlotteryserv.bizはGAEアプリに接続しています。

その一方でユーザ認証は同じくGCPの中の別のサービスであるIdentity Platformを使用しています。Identity Platformでは「認証ハンドラのカスタマイズ」からリンクされた「カスタムドメインを接続する」に上記ユーザ認証画面で独自ドメインを表示する方法が説明されています。ここを読めばわかるように、上記のユーザ認証画面で独自ドメインを表示するには、独自ドメインをFirebase Hostingに接続する必要があります。

つまり独自ドメインをGAEとFirebase Hostingで奪い合って競合する事態になります。LotteryServでは独自ドメインはGAEに接続し、ユーザ認証画面での独自ドメイン表示は諦めています。

FirebaseはもともとGoogleとは独立した会社であったFirebase社が2011年に開始したサービスだったのですが、2014年にGoogleに買収されてGCPの一員となった経緯があります。そのためFirebase社の名残がいろいろなところにあったり、今回のユーザ認証画面の表示の様に まだGCPに統合しきれていない部分が残っていたりします。

FirebaseがGCPに完全に統合されるまで、この対応は簡単ではないと思われます。


2021/09/27追記

FirebaseAuth.generateEmailVerificationLink()メソッドなどが生成するEメールアドレス確認のリンクも、同様にドメインがFirebaseですね。