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

2022年7月15日金曜日

Dialogflowを削除してもFirebaseプロジェクトが削除できない問題に対処 (エラー:削除を防ぐリーエンがプロジェクトに配置されました。)

Firebaseに新しいプロジェクトを追加しようとしたところ、プロジェクト数の上限が近づいていました。 

過去にActions on Googleを色々試していた時にサンプルを動かすためだけに作ったプロジェクトが多数あったため、それを削除して整理しようと思いました。

発生した現象

Firebaseコンソールでプロジェクトの設定画面からFirebaseプロジェクトを削除しようとすると、「削除を防ぐリーエンがプロジェクトに配置されました。削除を許可するには、リーエンを削除してください。」というエラーが表示され、削除できませんでした。

Dialogflowとリンクされていることが原因のようだったので、Dialogflowコンソールから該当するDialogflowエージェントを削除しました。

ところが、Dialogflowエージェントの削除後も同じエラーが表示され続け、Firebaseプロジェクトが削除できない状態になりました。

解決した方法

下記手順で、プロジェクトの削除を防いでいる「リーエン」を削除することで解決できました。

  1. gcloud CLI (Google Cloud CLI) をインストール
    参考: https://cloud.google.com/sdk/docs/install-sdk?hl=ja

  2. リーエンの一覧を確認
    >gcloud alpha resource-manager liens list --project my-project-name
    NAME                                                 ORIGIN                                                                                                                                                                                                                           REASON
    p703716169729-*********-****-****-****-************  You cannot delete this project because it is linked with a Dialogflow agent. Please follow the link to Dialogflow and delete the agent: https://console.dialogflow.com/api-client/#/agent/430c5fc3-****-****-****-************/  Deletion blocked by Dialogflow.
    
  3. liens/<NAME欄に表示されたリーエンの名前> の形式でリーエン名を指定して、下記コマンドを実行
    >gcloud alpha resource-manager liens delete liens/p703716169729-*********-****-****-****-************
    Deleted [liens/liens/p703716169729-*********-****-****-****-************].
    
  4. リーエンが削除されたことを確認
    >gcloud alpha resource-manager liens list --project my-project-name
    Listed 0 items.
    
  5. Firebaseコンソールに戻り、Firebaseプロジェクトを削除

2019年10月4日金曜日

Actions on Googleで使うFirebase Functionsの開発用ローカルサーバーを作る

Actions on Google のドキュメントやチュートリアルだとあまり詳しく書かれていない、Firebase Functionsの代わりにローカルサーバーを使用する環境を構築する方法です。

コードを1行変えて動作を確認するにも毎回Firebaseにデプロイして…という手間から解放されます…!

【参考記事】
Speed up Actions on Google development workflow with local fulfillment
https://medium.com/voiceano/speed-up-actions-on-google-development-workflow-with-local-fulfilment-7de17d5f166f

実行コマンドやjsonの設定内容も上記記事から引用させていただいています。大変参考になりました。ありがとうございます!

環境

Windows 10 Home (バージョン1903)
Node v10.16.3
firebase-functions @3.2.0
firebase-admin @8.6.0
ngrok @3.2.5
nodemon @1.19.2

設定手順

躓いたポイントは後でまとめるとして、まず全部うまくいった場合の手順を。

すでに、Firebase FunctionにデプロイしてDialogflowと連動して動作しているプロジェクトがある前提で進めます。

2019年10月1日火曜日

#100DaysOfCode R2 Day37-38

Day 37-38: September 29-30, 2019

Today's Progress:

  • FirebaseUIの導入
  • ログイン後、他のページに遷移させてみる
  • 他のページでもログイン後の情報を利用してみる

JavaScriptの読み込み順、実行順でとにかく引っかかっているなと思います。
ドキュメントを上から順に読んでその通りに並べても動かなくて、どこでinitializeしたインスタンスをどこで使って…というのを意識して読み込み順を整理すると動くようになりました。

ログイン後別のページにリダイレクトさせた際、 firebase.auth() の情報はどうやって引き継いだら…?と思ったのですが、普通に別ページにもfirebaseをinitializeするコードを入れて firebase が使えるようにすると、引き継ぐことができました。

どこまで引き継がれるかはここら辺で設定できるのかな?
認証状態の永続性

Google, Twitter, Email+Password でログインフローが動作することを確認。

Links to work:

2019年9月27日金曜日

#100DaysOfCode R2 Day34

Day 34: September 26, 2019

Today's Progress:

  • Firebase FunctionのRegionの変更

変更できました。今日は仕事関係を結構がんばってしまってあまりこちらは進められずという感じですが…。
結構会話の応答が遅い感じするので、Region変えたら速くなるかなとちょっと期待していたのですが、体感で分かるほどは速くならなかったです(笑)

ひとまず新プロジェクトへの移行作業は完了!

Links to work:

2019年9月26日木曜日

#100DaysOfCode R2 Day33

Day 33: September 25, 2019

Today's Progress:

  • Firebaseのプロジェクトを新しく立て直す(完了)

元々動いていた機能を一通りコピーできました。

対応内容↓

  • Dialogflowプロジェクトの作り直し、Restore
  • Actions API の認証情報(サービスアカウントキー)の再設定
  • Firebase Functions のデプロイ
  • Function URLをDialogflowに設定し直し
  • Firebase構成情報の設定し直し
  • Firebase Authenticationを有効化

あとは Function の Region も設定しなおさなければ。

Links to work:

  • なし

2019年9月25日水曜日

#100DaysOfCode R2 Day32

Day 32: September 24, 2019

Today's Progress:

  • Firebaseのプロジェクトを新しく立て直す

今使用しているプロジェクトが1年ほどまえに試作していたものをそのまま使っていて、Location(Region)がUSが選択されていたのですが、現在はTokyoが選べるようになっていて、後々使い続けるとしたら今のうちにTokyoに変更しておいた方が良さそうだったので、プロジェクトを新しく立て直すことにしました。
(Locationだけ変更はできなかった)

ここまで対応した内容。まだ途中です。

  • Firebase console から新しい名前のプロジェクトを取得
  • Cloud Firestoreの使用開始→なぜかエラーになる(「不明なエラーが発生しました」)→タイムラグがあるのか、10分程度時間が経つとエラーが解消された。
  • Google Cloud Platform consoleにもFirebase Consoleから登録した新しいプロジェクト名が表示されなかったが、同じくらいのタイミングで表示されるようになった。
  • .firebaserc で指定されているデフォルトプロジェクト名を、新しいプロジェクト名に書き換えてから firebase init

Links to work:

  • なし

2019年9月24日火曜日

#100DaysOfCode R2 Day31

Day 31: September 23, 2019

Today's Progress:

  • Hostingにデプロイして同じ操作ができることを確認
  • ログイン中のユーザーの告知を取得する

Loadボタンを押したタイミングで、ログインしているユーザーのuidを firebase.auth().currentUser; で取得し、それを元にクエリを作成して読み出すことに成功。

document ID を指定すると1件の .get() でdocumentだけが取得されるけど、 collectionに対してクエリを実行すると .get() で得られるのが複数件のdocumentの集合なのでforEachで回して読み取らないといけないのが、前にも同じところで躓いた気がする。

参考
コレクションから複数のドキュメントを取得する

JavaScript難しい…何度理解したと思っても少し書かない期間が空くと全部忘れてしまう…。

Links to work:

  • なし

2019年9月22日日曜日

#100DaysOfCode R2 Day30

Day 30: September 22, 2019

Today's Progress:

  • 自分のプロジェクトにFirebase Authを使用したルールを設定してみる

Firebase CLI を使用してルールをデプロイしたり、JavaScriptのコード内で firebase.auth().currentUser.uid でuidを取得してその値をCloud Firestore のDBに保存したりするやり方を試しました。

参考にしたドキュメント

Visual Studio Code に Firestore の .rules ファイル用の拡張機能があるのを発見。

Links to work:

2019年9月21日土曜日

Firebase Auth、Cloud Firestoreのセキュリティルールについてメモ

下記の動画の内容について、自分の理解のメモ。

このドキュメントからリンクされていた動画です。
Cloud Firestore セキュリティ ルールを使ってみる | Firebase


{database} →任意のdatabase名にmatchし、matchしたdatabase名を database という変数に格納する
{restOfPath=**} →これ以下のパスにあるすべてのドキュメント・コレクション

Cloud Firestoreでは、上の階層で指定されたルールは下の階層に引き継がれない
(Realtime Databaseの場合と異なる)

service cloud.firestore {
  match databases/{database}/document {
    // restaurantID = The ID of the restaurant doc
    match /restaurants/{restaurantID} {
      // restaurantID = The ID of the restaurant doc
      // reviewID = The ID of the review doc
      allow write: if reviewID == "review_234"
    }
  }
}

アクションは5種類
read

  • get
  • list

write

  • create
  • delete
  • update

request オブジェクトは「authオブジェクト」と「resourceオブジェクト」から成る

  • request.auth にユーザーの認証情報
  • request.resource.data にこのリクエストで渡すデータの内容

が入っている感じ

こんな感じで、ルールにはresourceオブジェクトのバリデーションっぽいものも書くことができる

service cloud.firestore {
  match /databases/{database}/documents {
    match /restaurants/{restaurantID} {
      match /reviews/{reviewID} {
        // score の値が数値の時のみcreateを許可する
        allow create: if request.resource.data.score is number &&
          // かつ、resource の reviewrID が 現在のユーザーのIDと一致する場合のみcreateを許可する
          request.resource.data.reviewerID == request.auth.uid;
      }
    }
  }
}
  • request.resource.data →リクエストで渡すデータの内容
  • resource.data →DBに既に保存されているデータの内容

を指す。

service cloud.firestore {
  match /databases/{database}/documents {
    match /restaurants/{restaurantID} {
      match /reviews/{reviewID} {
        // createのルール
        allow create: if request.resource.data.score is number &&
          request.resource.data.reviewerID == request.auth.uid;

        // updateのルール
        allow update: if request.resource.data.score is number &&
          request.resource.data.reviewerID == request.auth.uid &&
          // リクエストのscoreの値と、既にDBに保存されているscoreの値が同じ時のみupdateを許可する(=scoreの値を変更できないようにする)
          request.resource.data.score == resource.data.score;
      }
    }
  }
}

query で複数のデータのリスト(コレクション)を取得する場合、
ルールで「state が published なデータのみreadを許可する」となっていると、
「全部のデータを取得」のクエリはpermission denied error になる。(たとえ今あるデータがすべてstate == published だったとしても)
「state が publishedの全データを取得」というクエリなら成功する。

自動でstate == published のデータだけフィルターして返してくれたりはしない。
※1件だけを指定して取得するリクエストの場合は、データの内容をチェックしてルールに合致するか見て返す・返さないを判断してくれる。

function の形で再利用できるようにして整理することもできる。

2019年9月14日土曜日

#100DaysOfCode R2 Day21, 22

Day 21: September 13, 2019

Today's Progress:

  • Actions on Google 開発
    • Firebase Authentication

下記を読んで、

ここら辺からコピペして、とりあえず動くことを確認。

ログイン・ログアウト機能が作れるのは分かった。GoogleでもEmailでもできた。

ではそれで取得したトークン?とかをどうやって権限管理に使ったらいいのか分からない…?

Links to work:

  • なし

Day 22: September 14, 2019

Today's Progress:

  • Actions on Google 開発
    • Firebase Authentication

サンプルを動かしてみる?
FirebaseExtended/firechat: Real-time Chat powered by Firebase

と思ったけど、なんか違う感じがする…?firechatというもう出来上がってるプロダクト(Firebase authとかRealtime Databaseとかを使ってる)を導入する方法の説明みたいな気がする。

FirebaseUI というのが用意されていて、ログインUIはこれを使うのがよさそう。
https://github.com/firebase/firebaseui-web

YouTubeのFirecastもあった。
Using FirebaseUI Auth, on the Web - Firecasts - YouTube

ちょっとまだ情報を探して迷走中。

Links to work:

  • なし

2019年9月12日木曜日

#100DaysOfCode R2 Day20

Day 20: September 12, 2019

Today's Progress:

  • Actions on Google 開発
    • Updatesメソッドでドキュメントの一部を更新

昨日 set メソッドでFirestoreにデータを登録できることを試した時に、指定したドキュメントにすでに他のフィールドが存在しても、 set で渡したフィールドのみの状態に上書きされてしまうことが分かったので、部分的に更新する方法を調査。

update メソッド、または set メソッドに { merge: true } を付けてあげることで実現できるようでした。

var setWithMerge = cityRef.set({
    capital: true
}, { merge: true });

明日試すのはここら辺かなあ。
ウェブサイトで Firebase Authentication を使ってみる | Firebase

Links to work:

  • なし

#100DaysOfCode R2 Day19

Day 19: September 11, 2019

Today's Progress:

  • Actions on Google 開発
    • Firebase Hosting と Cloud Firestore の接続

Cloud Firestore のスタートガイドとそこにあった動画を参考に、Firebase Hosting に置いたウェブページ から Cloud Firestore のデータを操作できることを確認。

HTMLでシンプルな input フォームを設置して、JavaScriptにCloud Firestoreに docRef.set({ notice: "something" }) みたいなコードを書いて、Submitボタンのonclickで実行されるようにする感じ。とりあえずできました。

参考: Cloud Firestore を使ってみる | Firebase

またちょっと体内時計のずれる時期に入ってきて体力が辛い…。

Links to work:

  • なし

2019年9月10日火曜日

既存のFirebase Projectにサービスを追加する

既にFirebase Functions, Cloud Firestoreを使用しているプロジェクトに、Firbase Hostingを追加したかった。

結論

既存のプロジェクトディレクトリのルートから

firebase init hosting

とやって大丈夫です。

もう少し詳しく

実行しようとすると

Before we get started, keep in mind:
  * You are initializing in an existing Firebase project directory
? Are you ready to proceed?

(既存のFirebaseプロジェクトのディレクトリで初期化しようとしてるけど大丈夫?進めていいのね??)
と聞かれるので不安になりますが、まだ使ってないサービスを指定するなら大丈夫でした。

たとえばFunctionsとFirestoreを既に利用しているプロジェクトにHostingを追加した場合、

  • publicディレクトリの作成
  • firebase.jsonにhostingの設定を追記

が行われました。FunctionsやFirestoreの設定が上書きされてしまうことはありませんでした。
私の場合、元々firebase.jsonの中にはFirestoreの設定しかなかったのでこんな感じ。

【参考】

実行結果

C:\Users\Owner\workspace\myapp>firebase init hosting

     ######## #### ########  ######## ########     ###     ######  ########
     ##        ##  ##     ## ##       ##     ##  ##   ##  ##       ##
     ######    ##  ########  ######   ########  #########  ######  ######
     ##        ##  ##    ##  ##       ##     ## ##     ##       ## ##
     ##       #### ##     ## ######## ########  ##     ##  ######  ########

You're about to initialize a Firebase project in this directory:

  C:\Users\Owner\workspace\myapp

Before we get started, keep in mind:

  * You are initializing in an existing Firebase project directory

? Are you ready to proceed? Yes

=== Project Setup

First, let's associate this project directory with a Firebase project.
You can create multiple project aliases by running firebase use --add,
but for now we'll just set up a default project.

i  .firebaserc already has a default project, using myapp.

=== Hosting Setup

Your public directory is the folder (relative to your project directory) that
will contain Hosting assets to be uploaded with firebase deploy. If you
have a build process for your assets, use your build's output directory.

? What do you want to use as your public directory? public
? Configure as a single-page app (rewrite all urls to /index.html)? No
+  Wrote public/404.html
+  Wrote public/index.html

i  Writing configuration info to firebase.json...
i  Writing project information to .firebaserc...

+  Firebase initialization complete!

C:\Users\Owner\workspace\myapp>

2019年9月5日木曜日

#100DaysOfCode R2 Day14

Day 14: September 5, 2019

Today's Progress:

  • Actions on Google 開発
    • Cloud Firestore のデータの検索

できましたー!!!

db.collection(FirestoreNames.NOTICES) は取得できているのに db.collection(FirestoreNames.NOTICES).where(FirestoreNames.KEYWORD, '==', keyword) とするとデータが取得できない(Firebase FunctionsのログによるとMalformed responseというエラー)問題で悩んでいたのですが、Dialogflowのパラメータ名/Firestoreのフィールド名/index.js内の変数名の keyword を全て keyword0 に変更すると動くようになりました…原因はわかりません…

キーワード2つを組み合わせての検索もできました。

昨日セットアップしたローカルサーバー大活躍!確かにこれはいちいちFirebase Functionsにデプロイするよりずっと速いし手間がかからない。

Links to work:

  • なし

2019年8月31日土曜日

Actions on Google を Firebase Realtime Database に接続

Actions SDKを使用したAction on GoogleとFirebase Realtime Databaseを接続できるか試しました。

まだかろうじて接続できていることが確認できた段階ですが…

参考にしたページとうまくいった方法のメモ。

Firebaseのドキュメントを読む時、Actions on GoogleはNode.js のウェブアプリと考えて大丈夫そう。

準備

JavaScript でのインストールと設定
https://firebase.google.com/docs/database/web/start

これ↓に沿って進める。

Firebase を JavaScript プロジェクトに追加する
https://firebase.google.com/docs/web/setup

構成情報の入手方法
https://support.google.com/firebase/answer/7015592

こんな感じ

デプロイについてはここら辺も参考になる?
https://firebase.google.com/docs/cli/#deployment

ここ(ウェブでのデータの読み取りと書き込み)ここ(「本気のしりとり」Google Homeアプリを作りました。) を見て色々書いてみるも、 snapshot.val() の値が [object Promise] となってしまってうまくいかない…

↓↓↓

DBからの読み出しができたコード

ここを見て真似したらできた!

データの取得>はじめに
https://firebase.google.com/docs/database/admin/retrieve-data?hl=ja#section-start

やああああっっとできたああああああ

真似したコードはこれ

// Import Admin SDK
var admin = require("firebase-admin");

// Get a database reference to our posts
var db = admin.database();
var ref = db.ref("server/saving-data/fireblog/posts");

// Attach an asynchronous callback to read the data at our posts reference
ref.on("value", function(snapshot) {
  console.log(snapshot.val());
}, function (errorObject) {
  console.log("The read failed: " + errorObject.code);
});

以下、サンプルコードを改変してあいさつの言葉をDBから読みだすようにしたコード。

元コード: actions-on-google/actionssdk-say-number-nodejs: Say a number Actions SDK sample for Actions on Google

改変後

'use strict';

// Firebase App (the core Firebase SDK) is always required and
// must be listed before other Firebase SDKs
var firebase = require("firebase/app");

// Add the Firebase products that you want to use
require("firebase/auth");
require("firebase/database");

const functions = require('firebase-functions');
const {actionssdk} = require('actions-on-google');

const app = actionssdk({debug: true});

// Your web app's Firebase configuration
var firebaseConfig = {
  // Firebase console で取得した構成情報を貼り付け
};

// Initialize Firebase
firebase.initializeApp(firebaseConfig);

// データベースでデータの読み書きを行うには、firebase.database.Reference のインスタンスが必要
// Get a reference to the database service
var database = firebase.database();
var ref = database.ref("greeting/morning");

var greetWord = "Hi!";

// Attach an asynchronous callback to read the data
ref.on("value", function(snapshot) {
  console.log(snapshot.val());
  greetWord = snapshot.val();
}, function (errorObject) {
  console.log("The read failed: " + errorObject.code);
});

app.intent('actions.intent.MAIN', (conv) => {
  conv.ask('<speak>' + greetWord + '<break time="1"/> ' +
  'I can read out an ordinal like ' +
  '<say-as interpret-as="ordinal">123</say-as>. Say a number.</speak>');
});

// 以下、元のサンプルコードと同じ

1回しか読み込まれていない?

けどこのままではfirebase deploy したタイミングでしかDBの変更が反映されない様子。
トリガーのタイミングについてはここら辺?

Realtime Database トリガー
https://firebase.google.com/docs/functions/database-events?hl=ja

こう↓すると、MAIN intent が呼び出される度にDBが読み込まれて、すぐには反映されないけど次の回では反映されてるのが確認できた。
てことはやっぱりPromiseとかCallbackの使い方が間違ってるんだろうな…。

// Attach an asynchronous callback to read the data
function readDb() {
  ref.once("value", function(snapshot) {
    console.log(snapshot.val());
    greetWord = snapshot.val();
  }, function (errorObject) {
    console.log("The read failed: " + errorObject.code);
  });
}

readDb(); // firebase deploy のタイミングで読み込み

app.intent('actions.intent.MAIN', (conv) => {
  readDb();  // MAIN intent のタイミングで読み込み。
  // 次にMAIN intent を呼び出した時には反映されていることが確認できる。

  conv.ask('<speak>' + greetWord + '<break time="1"/> ' +
  'I can read out an ordinal like ' +
  '<say-as interpret-as="ordinal">123</say-as>. Say a number.</speak>');
});

2018年12月31日月曜日

firebase deploy --only functions のエラー (Command terminated with non-zero exit)

2019/08/29追記:現在は修正されているようです。詳細後述。

firebase deploy --only functions 実行時に Error: functions predeploy error: Command terminated with non-zero exit code4294963238 というエラーが発生した際の対処法。

発生したエラー

C:\Users\***>firebase deploy --only functions

=== Deploying to '***'...

i  deploying functions
Running command: npm --prefix "$RESOURCE_DIR" run lint
npm ERR! path C:\Users\***\%RESOURCE_DIR%\package.json
npm ERR! code ENOENT
npm ERR! errno -4058
npm ERR! syscall open
npm ERR! enoent ENOENT: no such file or directory, open 'C:\Users\***\%RESOURCE_DIR%\package.json'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\***\AppData\Roaming\npm-cache\_logs\2018-11-18T04_48_00_356Z-debug.log

Error: functions predeploy error: Command terminated with non-zero exit code4294963238

解決策

firebase.json の中の $RESOURCE_DIR%RESOURCE_DIR% に書き換える。

※Windows用の解決策。異なるOSを使ってチームで作業する場合などは使えない。

参考:
https://stackoverflow.com/questions/48345315/error-deploying-with-firebase-on-npm-prefix-resource-dir-run-lint

Try to replace $RESOURCE_DIR with %RESOURCE_DIR% in your firebase.json file.

成功時のログ

C:\Users\***>firebase deploy --only functions

=== Deploying to '***'...

i  deploying functions
Running command: npm --prefix "%RESOURCE_DIR%" run lint

> functions@ lint C:\Users\***\functions
> eslint .

+  functions: Finished running predeploy script.
i  functions: ensuring necessary APIs are enabled...
+  functions: all necessary APIs are enabled
i  functions: preparing functions directory for uploading...

+  Deploy complete!

Project Console: https://console.firebase.google.com/project/***/overview

追記

2019/08/29追記: 久しぶりにFirebase を使ったところ、今は直っている様子。
$RESOURCE_DIR のままでも上手くいきました。

Firebase CLI もWindowsもNode.jsも何もかもアップデートしているので、どれでうまくいくようになったのか分かりませんが…(苦笑)

上手くいった際のFirebase CLI のバージョンは 7.3.0 です。

C:\Users\***>firebase deploy --only functions

=== Deploying to '***'...

i  deploying functions
Running command: npm --prefix "$RESOURCE_DIR" run lint

> functions@ lint C:\Users\***\functions
> eslint .

+  functions: Finished running predeploy script.
i  functions: ensuring necessary APIs are enabled...
+  functions: all necessary APIs are enabled
i  functions: preparing functions directory for uploading...
i  functions: packaged functions (39.41 KB) for uploading
+  functions: functions folder uploaded successfully
i  functions: creating Node.js 8 function myFunction(us-central1)...
+  functions[myFunction(us-central1)]: Successful create operation.
Function URL (myFunction): https://us-central1-***.cloudfunctions.net/myFunction

+  Deploy complete!

Project Console: https://console.firebase.google.com/project/***/overview