- 投稿日:2020-05-30T18:18:13+09:00
firebase login ができない時の対処法
概要
ReactをFirebaseにHostingしようとした際にハマったのでメモ
状況
yarn create react-app my-appして
yarn add firebase-toolsして
firebase loginちなみにこの後に聞かれるY/nはどっちでもいいです。
エラー
何度やってもログインできない、、、。
対処法
調べたらこれをするといいらしい。
firebase login --no-localhostこれでもできない場合はsslの検証をパスする以下の環境変数を設定します。
export NODE_TLS_REJECT_UNAUTHORIZED=0firebase login解決
firebase init? What do you want to use as your public directory? (public) //buildにしますyarn buildfirebase deployで公開完了。
- 投稿日:2020-05-30T16:07:15+09:00
ReactアプリをFirebase Hostingにデプロイ
先日、初めてFirebaseを使ってデプロイする機会がありました。
基本的には案内に沿って進めるだけでしたが、せっかくなので手順をメモしておきます。前提
- デプロイするReactアプリがすでにある
- yarnが使える環境である
また、自分はDocker環境を使っていたので、Docker環境でデプロイするにあたっての補足も一部書いています。
Firebase側
新規登録・プロジェクト作成
Firebaseへアクセス
プロジェクトの作成
少し時間がかかりますが、これでプロジェクトが作成されます。
アプリを追加
ウェブアプリにFirebaseを追加
- 1 - アプリのニックネームを入力 + Firebase Hosting設定を有効化 して「アプリを登録」
- 2 - Firebase SDKを予約済みURLから使用する場合は、スクリプトを控えておき「次へ」(※予約済みURLについてはこちらも参照)
- 3 - Firebase CLIのインストール方法を確認して「次へ」
- 4 - Firebase Hostingへのデプロイ方法を確認して「コンソールに進む」
これでFirebaseプロジェクトにウェブアプリが追加されました。
Reactアプリ側
基本的には、Firebaseプロジェクトにアプリを追加した時に表示された手順で進めていきます。
Firebase SDKの導入
Firebase SDKを導入する方法としては
- 予約済みURLにあるものを読み込み使用する
- CDNで配信されているものを読み込み使用する
- ライブラリとしてインストールし使用する
の3つのやり方があり、Firebase SDK Snippetに関しては Firebaseプロジェクトの「設定」「プロジェクトを設定」のマイアプリから確認できます。
補足として、予約済みURLというのはFirebase HostingでのURLのことを指します。そのURL配下にSDKおよびアプリの識別情報のファイルが配置されるようになっており、それを読み込んでSDKを使用する形になります。
そのため、この方法はFirebase Hostingを使ってホスティングする場合のみ、使用可能です。
主に同じコードを複数のFirebase Hostingにデプロイする際に便利な方法のようです。自分も最初は予約済みURLでの方法にしていましたが、
$ yarn start
での通常のローカルサーバからはSDKを読み込むことができないために、Warningが出るのが気になりやめました。今回はライブラリとしてインストールして使用する方法で進めます。
ライブラリのインストール
$ yarn add firebase
.env
を作成設定値はFirebase SDK Snippetの「構成」から確認できます。
例
.env# Firebase REACT_APP_APP_KEY=※apikey REACT_APP_AUTH_DOMAIN=※authDomain REACT_APP_DATABASE_URL=※databaseURL REACT_APP_PROJECT_ID=※projectId REACT_APP_STORAGEBUCKET=※storageBucket REACT_APP_MESSAGING_SENDER_ID=※messagingSenderId REACT_APP_APP_ID=※appId REACT_APP_MEASUREMENT_ID=※measurementIdFirebase SDKの初期化を行うファイルを作成
各種Firebaseの機能を使うには最初に初期化処理を行う必要があります。
そのため、初期化処理をするファイルをあらかじめ用意しておき、機能を使うときにimportするようにします。例
libs/Firebase.jsimport firebase from 'firebase/app'; import 'firebase/analytics'; const config = { apiKey: process.env.REACT_APP_APP_KEY, authDomain: process.env.REACT_APP_AUTH_DOMAIN, databaseURL: process.env.REACT_APP_DATABASE_URL, projectId: process.env.REACT_APP_PROJECT_ID, storageBucket: process.env.REACT_APP_STORAGEBUCKET, messagingSenderId: process.env.REACT_APP_MESSAGING_SENDER_ID, appId: process.env.REACT_APP_APP_ID, measurementId: process.env.REACT_APP_MEASUREMENT_ID, }; firebase.initializeApp(config); export default firebase;Google Analyticsにデータ送信する設定を追記
自分の場合はindex.jsに追記しました。
最初は、SDK組み込みだけで自動的にデータ送信してくれるものと思っていましたが、firebase.analytics()
をやらないといけないようです。以下の内容を
ReactDOM.render
の上に追記。index.jsimport firebase from './libs/Firebase'; if (process.env.NODE_ENV === 'production') { firebase.analytics(); } . . .Firebaseプロジェクトのアプリとの連携
Firebase CLIの導入
$ yarn global add firebase-tools
Dockerの場合では、Node.jsコンテナ起動時のコマンドでインストールするようにしました。
これでfirebaseコマンドが使えるようになります。
firebaseへログイン
Dockerの場合は、OAuth認証で
9005
ポートを使用するので事前に開けておきます。$ firebase login
Firebase optionally collects CLI usage and error reporting information to help improve our products. Data is collected in accordance with Google's privacy policy (https://policies.google.com/privacy) and is not used to identify you. ? Allow Firebase to collect CLI usage and error reporting information? (Y/n)Firebaseはオプションで、CLIの使用状況とエラー報告情報を収集して、製品の改善に役立てます。データはGoogleのプライバシーポリシー( https://policies.google.com/privacy )に従って収集され、ユーザーの特定には使用されません。
FirebaseがCLIの使用状況とエラー報告情報を収集することを許可しますか? (はい/いいえ)
任意で回答。
To change your data collection preference at any time, run `firebase logout` and log in again.データ収集の設定をいつでも変更するには、
firebase logout
を実行して、再度ログインします。Visit this URL on this device to log in: https://accounts.google.com/o/oauth2/auth?XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Waiting for authentication...認証のためのURLが表示されるので、ブラウザでアクセス。
内容を確認して「許可」
✔ Success! Logged in as XXX@gmail.com無事に認証できるとCLI側はこの表示が出ます。
また、ブラウザ側では以下のような表示が出ます。
連携・初期化処理
$ firebase init? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then Enter to confirm your choices. (Press <space> to select, <a> to toggle all, <i> to invert selection) ❯◯ Database: Deploy Firebase Realtime Database Rules ◯ Firestore: Deploy rules and create indexes for Firestore ◯ Functions: Configure and deploy Cloud Functions ◯ Hosting: Configure and deploy Firebase Hosting sites ◯ Storage: Deploy Cloud Storage security rules ◯ Emulators: Set up local emulators for Firebase featuresこのフォルダに設定するFirebase CLI機能はどれですか?スペースを押して機能を選択し、Enterを押して選択を確認します。 (スペース を押して選択、a を押してすべてを切り替え、i を押して選択を反転します)
今回は
Hosting
のみ選択。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. ? Please select an option: (Use arrow keys) ❯ Use an existing project Create a new project Add Firebase to an existing Google Cloud Platform project Don't set up a default projectまず、このプロジェクトディレクトリをFirebaseプロジェクトに関連付けます。
複数のプロジェクトエイリアスを作成するには、firebase use --add、
ただし、ここではデフォルトのプロジェクトを設定します。今回はすでにFirebaseプロジェクトを作っているので
Use an existing project
を選択。? Select a default Firebase project for this directory: (Use arrow keys) ❯ project-name (project-name)このディレクトリのデフォルトのFirebaseプロジェクトを選択:(矢印キーを使用)
連携させるプロジェクトを選択。
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)パブリックディレクトリは、プロジェクトディレクトリを基準にしたフォルダです。
firebase deployでアップロードされるホスティングアセットが含まれます。もし、あなたが
アセットのビルドプロセスがある場合は、ビルドの出力ディレクトリを使用します。
$ yarn build
での生成物は/build
に作成されるので、build
と入力。? Configure as a single-page app (rewrite all urls to /index.html)? (y/N)SPAアプリとして構成しますか(すべてのURLを/index.htmlに書き換えます)? (はい/いいえ)
今回はSPAなので
y
を入力。✔ Wrote build/index.html i Writing configuration info to firebase.json... i Writing project information to .firebaserc... ✔ Firebase initialization complete!これで設定ファイルが作成されて、連携は完了です。
Firebase Hostingへデプロイ
ビルドして、その生成物をデプロイします。
$ yarn build $ firebase deploy=== Deploying to 'project-name'... i deploying hosting i hosting[project-name]: beginning deploy... i hosting[project-name]: found 19 files in build ✔ hosting[project-name]: file upload complete i hosting[project-name]: finalizing version... ✔ hosting[project-name]: version finalized i hosting[project-name]: releasing new version... ✔ hosting[project-name]: release complete ✔ Deploy complete! Project Console: https://console.firebase.google.com/project/project-name/overview Hosting URL: https://project-name.web.app表示されるホスティングURLにアクセスして、アプリの内容がちゃんと表示されれば、無事デプロイ完了です。
Firebaseを初めて使いましたが、思っていた以上に簡単にデプロイ出来てよかったです。
Reactとの相性もいいみたいですし、他の機能も使っていきたいなーと思います。
可能性が広がりますね!いずれはデプロイフローをCIで自動化するつもりなので、自動化できたら追記するかもしれません。
参考リンクまとめ
- 投稿日:2020-05-30T14:59:04+09:00
React 基本のき
トランスコンパイラ
babelがいい感じに変換してくれてる
webpack
使われいる
<script src="/static/js/bundle.js"></script>Component
クラスコンポーネント
import React, { Component } from "react"; class App extends Component { render() { return ( <React.Fragment> <label htmlFor="bar">bar</label> <input type="text" onInput={() => { console.log("I am clicked"); }} /> </React.Fragment> ); } }関数コンポーネント
import React from "react"; const App = () => { return ( <React.Fragment> <Cat /> <Cat /> <Cat /> <Cat /> </React.Fragment> ); }; const Cat = () => { return <div>Coco</div>; };import React from "react"; function App() { return ( <React.Fragment> <label htmlFor="bar">bar</label> <input type="text" onInput={() => { console.log("I am clicked"); }} /> </React.Fragment> ); }props
- componentの属性のこと
- あるデータの属性に参照できるもののこと
const App = () => { const profiles = [ { name: "Coco", age: 20 }, { name: "Heck", age: 22 }, { name: "NoName" } ]; return ( <React.Fragment> {profiles.map((profile, index) => { return <User key={index} name={profile.name} age={profile.age} />; })} </React.Fragment> ); }; // ここで受け取ってるprops const User = props => { return ( <div> Hi, I am {props.name}, and {props.age} years old </div> ); }; // 初期値設定できる User.defaultProps = { age: 1 }; export default App;
- 投稿日:2020-05-30T13:53:33+09:00
【React】関数コンポーネントの引数に分割代入を使う
はじめに
参加したReactの勉強会で出てきた分割代入について調べてみた。
分割代入とは
ES2015から追加された構文でドキュメント(MDN)に書いてある説明はこんな感じ。
分割代入 (Destructuring assignment) 構文は、配列から値を取り出して、あるいはオブジェクトからプロパティを取り出して別個の変数に代入することを可能にする JavaScript の式です。
Reactで使ってみる
親コンポーネントから子コンポーネントにpropsでテキストを渡して表示するだけの適当なコードで動作確認してみた。
App.jsximport React from "react"; import Text from "./Text"; import "./styles.css"; const App = () => { const text1 = "hogehoge"; const text2 = "fugafuga"; return ( <div className="App"> <Text text1={text1} text2={text2} /> </div> ); }; export default App;1.引数に
props
を渡す個人的には一番最初に勉強したやり方。
Reactの公式ドキュメントにも同様の書き方が紹介されている。この関数は、データの入った “props”(「プロパティ」の意味)というオブジェクトを引数としてひとつ受け取り、React 要素を返すので、有効な React コンポーネントです。
Text.jsximport React from "react"; const Text = props => { return ( <div> <p>{props.text1}</p> <p>{props.text2}</p> </div> ); }; export default Text;
props
がオブジェクトかどうか確認。console.log(props); // Object {text1: "hogehoge", text2: "fugafuga"}2.引数に
props
を渡す&関数内で分割代入分割代入を使うことで
props.text1
のような冗長な書き方をしなくて良くなる。
サンプルコードは短いのでそうでもないが、コード量が増えるといちいちprops.
を書くのがめんどい。Text.jsximport React from "react"; const Text = props => { // 分割代入 const { text1, text2 } = props; return ( <div> <p>{text1}</p> <p>{text2}</p> </div> ); }; export default Text;
const { text1, text2 } = props;
の部分は下記コードと同じことをしている。
text1
というimutableな変数が定義され、そこにprops.text1
が代入されるイメージ。
const { text2, text1 } = props;
のように順番を逆さにしてもOK。const text1 = props.text1; const text2 = props.text2;3.引数に分割代入を使う
引数に分割代入を使うことでさらにコードを短く書くことができる。
props
で書くよりも、引数が明示的になるためコードの見通しが良くなる。Text.jsximport React from "react"; const Text = ({ text1, text2 }) => { return ( <div> <p>{text1}</p> <p>{text2}</p> </div> ); }; export default Text;
- 投稿日:2020-05-30T13:35:41+09:00
reactでアニメーションを実装する
最近の勉強で学んだ事を、ノート代わりにまとめていきます。
主に自分の学習の流れを振り返りで残す形なので色々、省いてます。
Webエンジニアの諸先輩方からアドバイスやご指摘を頂けたらありがたいです!アニメーションの実装
gifファイルの場合、実装は簡単だが容量が大きくなることも
import animation from "images/animation.gif"; ・ ・ <image src={animation} alt="トップ画像" />Lottieで実装する!
Lottieとは?
Lottieという動画をアプリに組み込むためのライブラリを使うといいよ
JSONファイルを組込むので格段に軽くなる
必要なものをAirbnbがほとんど用意してくれててすごい?1.ZXPInstallerをDL:http://aescripts.com/learn/zxp-installer/
2.BodymovinをDL(Aeのプラグイン):https://github.com/airbnb/lottie-web/
3.アプリに組み込みたい動画をAeで作成
4.動画をBodymovinでJSONで書き出し
5.プレビューでエラーがないか確認
6.問題なければ実装(orデータの受け渡し?)実装の際はLottieをインストールし
$ npm i react-lottie
これでOK!
import React, { Component } from 'react' import Lottie from 'react-lottie' import animationData from '../lotties/4203-take-a-selfie.json' class UncontrolledLottie extends Component { render(){ const defaultOptions = { loop: true, autoplay: true, animationData: animationData, rendererSettings: { preserveAspectRatio: 'xMidYMid slice' } }; return( <div> <h1>Lottie</h1> <p>Base animation free from external manipulation</p> <Lottie options={defaultOptions} height={400} width={400} /> </div> ) } } export default UncontrolledLottie細かいオプションはLottieのドキュメントで確認できる!
参考資料
・Lottie
・How To Add Animations to React Apps with React-Lottie
- 投稿日:2020-05-30T10:42:43+09:00
【React】 useStateで配列を保存するときの注意点
useState
で配列を保存する時は、
新しい配列を生成して保存しないと再描画されません。サンプルコード
×: 再描画されない
const [value, setValue] = React.useState(null) value.push(props.newValue) setValue(value)○: 再描画される
const [value, setValue] = React.useState(null) setValue({...value, props.newValue})理由
Reactでは
state
の値が変化した時にコンポーネントが再描画されます。stateの値の変化を、
Object.is()
で判定しているとのことです。なので、push
やsplice
では前回と同じ値と判定されるそうです。そのため、再描画が起きないので、
{...array, props.newValue}
などで値をコピーした新しいオブジェクトを生成してstate
に保存すると再描画されます。参考
- https://gotohayato.com/content/509/
- https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/is
- http://jsstudy.hatenablog.com/entry/Convert-to-JSON-when-comparing-arrays-and-objects-in-JavaScript
おまけ
新しい配列を生成する以外にも、immutable.jsというのを使っても解決できるそうです。