KAEDE Hack blog

JavaScript 中心に ライブラリなどの使い方を解説する技術ブログ。

Firebase First Try

why

Freeeの課題で1weekで家計簿を作って公開しろと言われて,これなら簡単だろうと 安易に手を出した.NoSQL?

だがかなり苦戦した.正解は後半のRight Choiseにある

無料で簡単なホスティングcrudができると聞いた.

f:id:kei_s_lifehack:20200210211759p:plain

Projectをスタートして,html body のbtmにおくscriptがもらえる

f:id:kei_s_lifehack:20200210211951p:plain

firebaseのCLIをinstallする,by npm

npm install -g firebase-tools

7.12が入った

firebase login

Googlesign inできる

f:id:kei_s_lifehack:20200210212707p:plain

f:id:kei_s_lifehack:20200210212758p:plain

hostingであってるはず

f:id:kei_s_lifehack:20200210213020p:plain

err, PRJのcreateに失敗している....なぜだ,GCPの問題??

f:id:kei_s_lifehack:20200210213343p:plain

logのfileをみると409ERRが出ている

f:id:kei_s_lifehack:20200211004317p:plain

firebase projects:create でも同じエラーが出る.

ググるGoogle Admin ConsoleからEnableするとあるが

support.google.com

admin.google.com is used for G Suite accounts only. Regular Gmail accounts cannot be used to sign in to admin.google.com. Learn More

と出てしまってloginできない.

GCPではないと教えていただき,

unique idとあるのでproject name, とunique project idを変えた(kaede-house)にしたら動いた!!!

f:id:kei_s_lifehack:20200211032153p:plain

ref

www.youtube.com

4min

web GUIから生成されるapi key, auth domeinなどの情報がCLIで生成するとどこだか見当たらない

prj nameとapp nicknameなどが同じでいいのかどう分けるのかわからん

でもホストできそうな気がしてきた

f:id:kei_s_lifehack:20200211034315p:plain

今度はexisting projectを選んでinit した

かえパンマン!!!新しいえらーよ!!!

f:id:kei_s_lifehack:20200211034737p:plain

stackoverflow.com

"Set up Cloud Storage in FB console"?

setting のこれをEAST ASIAにすればいいのか?物理locationのことだったのか?

north-east1にした,物は試しだろ

そこまでは動いたが,indexのfetchでerrが出た!流石に寝るか

f:id:kei_s_lifehack:20200211035816p:plain

2/12

qiita.com

この記事の通りにしたら できちゃった!!

f:id:kei_s_lifehack:20200212011113p:plain

firebase deployでひらけた.

こっちはwebからアクセスできる???

kaedehouse.firebaseapp.com

f:id:kei_s_lifehack:20200212011519p:plain

さてここからどうHTMLを反映してDBを読み込むのか....

firebase serveだとlocalhost 5000で開く.さっきのと何が違うのかわからん

serveとdeployの違いを教えていただいた.localhostだしそうだよね

flaviocopes.com

この記事の通りにfirebase.json

    "headers": [
      {
        "source" : "**/*.@(jpg|jpeg|gif|png|css|js)",
        "headers" : [ {
            "key" : "Cache-Control",
            "value" : "max-age=1000000" //1 week+
        } ]
      }
    ]

を追加して jpg|jpeg|gif|png|css|js が1 week cacheされるようにした.

こっからどうfirebase cloudに連携するのかわからん

qiita.com

これを参考にしたが,

f:id:kei_s_lifehack:20200213013134p:plain

こんなコードは一切出てこない.UIが全く違う!!

でも読み込まれるindex.htmlは直下じゃなくてpublicにあることがわかった こっちのindexのtitle変えてdeployしたら反映された.ヨシ!

f:id:kei_s_lifehack:20200213013312p:plain

あとはDBをどう連携するか..しんどい...

崎山様....本日もありがとうございます...

create databaseを見つけてtest modeで作成した

f:id:kei_s_lifehack:20200213014653p:plain

このまま公開するとsecurity的にボコボコにされるらしい,やばいな

この構成OBJが欲しいのだが, add app のところでもコードが手に入らない.どうしたらいいのだろう

f:id:kei_s_lifehack:20200213033237p:plain

f:id:kei_s_lifehack:20200213033414p:plain

f:id:kei_s_lifehack:20200213033310p:plain

webのGUIからstorageをstartできた.

f:id:kei_s_lifehack:20200213033715p:plain

とりあえずgstaticのscriptをpublic/index.html にpasteした

だがここがわからんな,

f:id:kei_s_lifehack:20200213034155p:plain

今日はここまでだ!!API KEY, AUTHDOMEIN, PRJ ID, どこで取れるか全くわからん!!

Cloud Firestore と App Engine: 同じプロジェクトで Cloud Firestore と Cloud Datastore の両方を使用することはできません。両方を使用すると、App Engine を使用するアプリが影響を受ける可能性があります。別のプロジェクトで Cloud Firestore を使用してみてください。

公式によると両方は使えないらしい.firestoreの方使えばいいのか? database,strageどちらかのタブってこと?

GCP使うの???サイトと違いすぎる!!

f:id:kei_s_lifehack:20200213203924p:plain

GCPは使わなそう.さっきのsettingから拾ってきたproject idとかからdomein を生成するみたい

f:id:kei_s_lifehack:20200213205734p:plain

このYoutubeのUIは全然違う.こんな風には絶対にでない.

f:id:kei_s_lifehack:20200213210821p:plain

ごちゃごちゃしてわかりにくいからとりあえずこれに合わせるところまで作ろう.

github.com

まずはmochajsとかがん無視してindexの初期のごちゃついたコードを消す.

f:id:kei_s_lifehack:20200213211106p:plain

次にgstaticのコードを...どこだ...見つからん

色々あるけどまずはJS projectにaddからしろって言われるしいいか.....

sender id以外は埋まった!!!大きな進歩だ

f:id:kei_s_lifehack:20200213212405p:plain

これの後の選択肢が無いんだよな,全部にしていいのか...わからん...

f:id:kei_s_lifehack:20200213212726p:plain

Error: Error fetching Firestore indexes が出た.これ全部ONにすることが悪いのか???

エラー出てるけどhostingはいける,ここでauthにアクセスできるのか?console.logで見てみるか

Not Aborted???

f:id:kei_s_lifehack:20200213213552p:plain

初期だとpublicのfileしか読み込めなくなってるとかかな,

index内のscriptでconsole.logしてfirebase.store() を出したが not definedになった,ビルトインというわけでは無いのか...

とりあえずjsをpublicの外から読み込むためにはfirebase.json をこのルール使えばいいのかな?

f:id:kei_s_lifehack:20200213213735p:plain

したらdeployがindexと404の2 filesから37filesに大幅に増えた!!

しかし404を返してしまう....

indexと同じ位置にあるはずなのに

f:id:kei_s_lifehack:20200213220723p:plain

とりあえず勧められた通りにquick startをしよう.gitからclone, project としてadd, init で全て追加.locationをsouth asia で追加.

動かんンンンン,ボタン押せないし,globalとかで怒られてる...

f:id:kei_s_lifehack:20200213222540p:plain

f:id:kei_s_lifehack:20200213222614p:plain

全くquickstartしないんだが....

どうやらversion違いでmaintainされてない可能性があるらしい.放置だ.

諦めよう.最低限オンラインでcrudが動けばいいから,なんとかしてさっきのkaedehouseのアプリでcloud firebaseを動かせばいいか

collectionやdocumentといった不思議な形のdbを動かせればそれだけで第一歩だろ......

firebase.google.com

同じディレクトリのtest.firestore.jsが読み込めない問題は解決しない.

Elementの構成を見てみるとcloudのjsはあるけどtest.firebase.jsは無いから ここに無いってことになる...???

f:id:kei_s_lifehack:20200215061956p:plain

https://stackoverflow.com/questions/60233835/why-firebase-does-not-read-my-js-in-same-directorystackoverflow.com

質問をした.誰か答えてくれるかな...

とりあえずindexのscript tagに入れて読み込ませたけど,globalのerrは意味がわからないし,読み込んだところでfirebase deploy してブラウザで見てみても何も無い

firebase.google.com

Get started with Cloud Firestore  |  Firebase

この二つにしたがってるんだが全くうまくいかない何もわからない,積んだ

黄色いいエラーがわからなかった.ここで諦める

logger.tsで出てるもんは無理だろ

gstatic消したら消えたのでgstaticに関係することがわかった,でバックはこうやって地道に一つづつ消してやっていくものだったな,忘れていたよ

www.youtube.com

この動画の通りにauthからやっていくようにした. GUIからgoogleをenableにして,support emailを登録して, appをconsole.logで見れるようになった.

deployを待ちながらDownloadが5MBを超えたのをみて,「これいきすぎるとspark planでも課金しろって出ないか? データを使用しないためにserve, localhostがあるのでは?」と気づいてdeployをやめてserveするようにしたら立ち上がるの早いし,データを消費しなくなった.ただcakeのbin/cake serverと同じで一つはterminalを占有していないと使えないみたいだ.学習.

GCPで結局Entityを作る

f:id:kei_s_lifehack:20200215090439p:plain

このUIは出てこない,辛い

f:id:kei_s_lifehack:20200215090633p:plain

GCPだとdocumentではないんだよね,それでdocumentにアクセスしても仕方ないし,これは適用できないかな

Right Choise

何かがおかしいのでProjectごと作り直すことにした

DBを作成

f:id:kei_s_lifehack:20200215123713p:plain

location is asia-southeast

初手でDB作ったら無事にGCPではなくてCollectionがでた!

f:id:kei_s_lifehack:20200215124054p:plain

ここから< >マークを叩いてadd app

前探していたものがすぐ出た

f:id:kei_s_lifehack:20200215124728p:plain

でもhostingをskipして気軽にfirebase initが打てないとなると

indexとかfirebase.jsonとか生成しないし,このscriptどこに打つかわかんないな

とりあえずこの順番で適当に作ったindexにpasteした

  <!-- Insert these scripts at the bottom of the HTML, but before you use any Firebase services -->

  <!-- Firebase App (the core Firebase SDK) is always required and must be listed first -->
  <script src="/__/firebase/7.8.2/firebase-app.js"></script>

  <!-- If you enabled Analytics in your project, add the Firebase SDK for Analytics -->
  <script src="/__/firebase/7.8.2/firebase-analytics.js"></script>

  <!-- Add Firebase products that you want to use -->
  <script src="/__/firebase/7.8.2/firebase-auth.js"></script>
  <script src="/__/firebase/7.8.2/firebase-firestore.js"></script>
    
<!-- The core Firebase JS SDK is always required and must be listed first -->
<script src="https://www.gstatic.com/firebasejs/7.8.2/firebase-app.js"></script>

<!-- TODO: Add SDKs for Firebase products that you want to use
     https://firebase.google.com/docs/web/setup#available-libraries -->
<script src="https://www.gstatic.com/firebasejs/7.8.2/firebase-analytics.js"></script>
  <!-- Initialize Firebase -->
  <script src="/__/firebase/init.js"></script>

<script>
  // Your web app's Firebase configuration
  var firebaseConfig = {
    apiKey: "AIzaSyAd8fUtVT1hFbvK-GqNMXjM5uYK4Jqqrds",
    authDomain: "cloud-db-dadfe.firebaseapp.com",
    databaseURL: "https://cloud-db-dadfe.firebaseio.com",
    projectId: "cloud-db-dadfe",
    storageBucket: "cloud-db-dadfe.appspot.com",
    messagingSenderId: "25503280923",
    appId: "1:25503280923:web:bf5bae15a978432d25edbe",
    measurementId: "G-KX73EC88VB"
  };
  // Initialize Firebase
  firebase.initializeApp(firebaseConfig);
  firebase.analytics();

このままだとfirebase.app.jsとかが読み込めないから, 仕方なくinitする....選択肢が不安だ....

firestoreだけのoptionで作ってみる

firebase serveは動かなかった,一度deployが必要なのか?

hostingとfirebase cloud込みでinitした.

するとpublic/index.htmlが結構書かれた状態で生成される.

ここのbodyのscript抜いて,style抜いて

最初にgstatic/app.js, firestore.js入れる

npmでfirestore7.8.2入れる

bodyにconst = firebaseを入れる

ここで一旦serveしてもあの黄色いエラーでるわ,すでに被ってる?

f:id:kei_s_lifehack:20200215132505p:plain

gstaticで使ってる分のjsを抜いてみた

そうしたら黄色は消えたけど,

Uncaught ReferenceError: require is not defined
Uncaught ReferenceError: firebase is not defined

は消えない,書くところが違うのか? いや,なぜnodeが読み込まれないんだろう

ここはnodeで動かしてみよう,terminalで

const firebase = require("firebase");
// Required for side-effects
require("firebase/firestore");

ダメだった.script srcで別ファイルから読み込んだら 今度は<が入ってしまうエラーに当たった.

firebase.jsonをdefaultの

{
  "firestore": {
    "rules": "firestore.rules",
    "indexes": "firestore.indexes.json"
  },
  "hosting": {
    "public": "public",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  }
}

からgithubサンプルの

{
  "hosting": {
    "public": "."
  }
}

に変えて試す

f:id:kei_s_lifehack:20200215143837p:plain

逆になんども読み込まれる黄色いエラーが出た

jsonを戻してpublicに並列させたら読み込んだ

しかしここが治らん,謎

f:id:kei_s_lifehack:20200215151208p:plain

inti.jsから出てるエラーはやはりfirebaseが定義されていないことからきていた

f:id:kei_s_lifehack:20200215151935p:plain

nodeが動かないエラー,

stackoverflow.com

こうやってwebpuckにすればいけるのか??

しなかった!!! differとscopeの問題だった!!!

hostingで読み込まれているので

      document.addEventListener('DOMContentLoaded', function() {
         // 🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥
         // The Firebase SDK is initialized and available here!
        
         //firebase.database().ref('/path/to/ref').on('value', snapshot => { });
        
         // 🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥

        try {
          let app = firebase.app();
          let features = ['auth', 'firestore', 'messaging', 'storage'].filter(feature => typeof app[feature] === 'function');
          document.getElementById('load').innerHTML = `Firebase SDK loaded with ${features.join(', ')}`;
        } catch (e) {
          console.error(e);
          document.getElementById('load').innerHTML = 'Error loading the Firebase SDK, check the console.';
        }

        console.log(firebase.firestore());
      });

DOM content loadedのスコープにかいたら ここまで行けたぜ!!!

f:id:kei_s_lifehack:20200215181341p:plain

とりあえずcollection posts作ってcolにmsgだけ入れて試してみる

        await db.collection('posts').add(
            { 
                msg: '1st insert'
            }
        );

だと

Uncaught SyntaxError: await is only valid in async function

とエラーが出る

www.youtube.com

こっちに沿ってやってみる

collection: post, id my first post, title: My First Firebase Post,

GUIで作成

srcのfirestore.jsを確認

        let myPost = db.collection('posts').doc('first post');

でpostsにアクセスできるが,ここからさらにgetのpromiseを?使って

         myPost.get()
              .then(doc => {
                  const data = doc.data();
                  document.write( data.title + `<br>` );
                  document.write( data.createdAt );
                  console.log(data);
              })

で読んだcolumが表示された!

{createdAt: ho, title: "My First Firestore Post", views: 1}createdAt: ho {seconds: 1581865200, nanoseconds: 0}title: "My First Firestore Post"views: 1__proto__: Object

が出る

f:id:kei_s_lifehack:20200217080921p:plain

1 weekかけてCRUDのReadが完成だ...

getの代わりにonSnapShotを使えば

        myPost.onSnapShot(doc => {

に置き換えるとReal time streamになるはずだが,そんなfuncはないとエラーが出た..

public/に置いてるapp.jsに書き込んで試してみる

これでも使えなかった,OnSnapShotなしでいけるか?

次はこの動画のUpdate をやる

<h1 id='title'>default title</h1>をhtmlに追加

                    document.querySelector('#title').innerHTML
                    = data.title

でdata.titleに今のを上書きし

<input onChange='updatePost(event)'>

    function updatePost(e) {
        const db = firebase.firestore();
        const myPost = db.collection('posts').doc('first post');
        myPost.update({ title: e.target.value });
    }

ではeが読み取れなくてupdate できなかった!

webからのcreateもできてないし公式を見よう

さっきの動画だと,collectionもdocumentも作ってから追加していたが このやり方では両方なくても自動生成してくれるらしい

データを追加する Cloud Firestore はデータをドキュメントに保存します。ドキュメントはコレクションに保存されます。データを初めてドキュメントに追加すると、Cloud Firestore によってコレクションとドキュメントが暗黙的に作成されます。コレクションやドキュメントを明示的に作成する必要はありません。

DOMcontentLoadedのscopeにこれを追加したら生成された

db.collection("users").add({
    first: "Ada",
    last: "Lovelace",
    born: 1815
})
.then(function(docRef) {
    console.log("Document written with ID: ", docRef.id);
})
.catch(function(error) {
    console.error("Error adding document: ", error);
});

f:id:kei_s_lifehack:20200217090830p:plain

これは読み込まれるたびに生成される

input でvalueを流すfunc を作ればこれでとりあえずCREATEできるかな

document.addEventListener('DOMContentLoaded', event => {
        let app = firebase.app();
        let db = firebase.firestore();

        db.collection("items").get().
        then(function(querySnapshot) {
            querySnapshot.forEach(function(doc) {
                let data = doc.data();
                console.log('id: ', doc.id, ": ", doc.data());
            });
        });
        // here jq click, does not work
      });

function OnButtonClick() {
    let app = firebase.app();
    let db = firebase.firestore();
    db.collection("items").add({
        name: 'added 0314',
        price: 0314,
        purpose: 'browser',
    })
}

content loadedのなかでjqの.clickから呼んでも,onChangeから呼んでも insertはできなかった.単純にfunctionを実行するとその値は実行される.

event同士干渉してしまっているのか?わからない.

document.addEventListener('DOMContentLoaded', event => {

のスコープに

    $('.submit').on('click', function(e){
        e.preventDefault();

let name = $('#name').val();

jqでinputの値をとって送信すると行けた!