Web初心者でもモダンなReact, Redux, FirebaseでTo-Doを作る3 ~Firebase~

Web初心者でもモダンなReact, Redux, FirebaseでTo-Doを作る3 ~Firebase~:

本記事はWeb初心者でもReact, Redux, FirebaseでTo-Doシリーズ3記事目です.

(いつのアドベントカレンダーだよ)


はじめに

厨二病まっさかりの浅野です。

Firebaseを導入して認証させたいです。が、その前にやらねばならないこと(redux-thunk, react-router-dom)がとても面倒だったので

1.ディレクトリ構成をいじる。
componentにAppディレクトリを作る
conatinerにAppディレクトリを作る

2.react-router-dom をインストール、設定し、Login ページ, SignUp ページを追加する

react-router-domをインストールして、Header, Signup, Loginを追加

3.redux-thunkでactionsを非同期対応させる。

actionsをredux-thunk風に書く

ところまでははしょります(いきなりテキトーです)

reduxはパッケージごとのかみあわせも微妙な感じがしますね、

公式の非同期処理サンプルではDispatchを繰り返してすごいことしてますが、多分DispatchはActionの中に書けばOKです。
Redux公式のRouterのやつも参考にしました。


0. Firebaseとは

Firebase社により運営されるWeb開発Platformです。DB、Hosting、認証が素人でも簡単に使えます。

Cloud Functionsがサーバーレスと騒がれていますが、今回は認証とDBとHostingを紹介します


1. Firebase Project作成、firebase SDK

https://console.firebase.google.com/u/0/

にアクセスして、プロジェクトを作りましょう



スクリーンショット 2018-12-14 12.24.27.png


とりあえずHosting, Database(FireStore)を左のメニューバーの開発→Hostingから使ってみるを押して説明を読みましょう。FireStoreはロックモードじゃない方ではじめましょう



スクリーンショット 2018-12-14 12.24.51.png


このあとは

npm install -g firebase-tools 
loginしてプロジェクトをはじめましょう。

今回はfirestore, cloud storage, hostingを使うのでまずはそれらを選択しましょう

firebase login 
 
firebase init 
initでプロジェクトが追加できない場合はprojectnameに先ほど入力した名前をいれてください

firebase use --add projectname 
しましょう

そのあとは下記以外は何も入力せずにEnterを押すとデフォルト値になるので今回はそのままいきましょう

? What do you want to use as your public directory? (public) build 
HostingにDeployされるディレクトリのみcreate-react-app自動生成のbuildに名前を変更します

Firebase initialization complete!が表示されたら完了です。一回デプロイしてみます。

npm run-script build 
firebase deploy 
Deploy complete!が表示されたら完了です!

FirebaseはおそろしいことにこれだけでProductionにDeployができてしまいます。

deployしたアプリはHostingにあるURLから見れます。

さてFirebaseは認証がとても簡単にできるのでまずは認証の機能とUserの概念をTo-Doに追加しましょう。

様々なサービスの認証が利用できますが、今回はGithub認証を使ってみたいと思います。

まずはアプリとFirebaseの連携させます。SDKもインストールしましょう
これを参考にしましょう。

src/以下にfirebaseディレクトリを作ってそこに作成します

npm i firebase --save 
mkdir firebase 
cd firebase 
touch index.js config.js 
firebase/config.js

export const firebaseConfig = { 
    apiKey: "<API_KEY>", 
    authDomain: "<PROJECT_ID>.firebaseapp.com", 
    databaseURL: "https://<DATABASE_NAME>.firebaseio.com", 
    projectId: "<PROJECT_ID>", 
    storageBucket: "<BUCKET>.appspot.com", 
    messagingSenderId: "<SENDER_ID>", 
  }; 
 
firebase/index.js

import firebase from 'firebase'; 
import {firebaseConfig} from './config.js'; 
 
export const firebaseApp=firebase.initializeApp(firebaseConfig); 
export const firebaseAuth=firebase.auth; 
export const fireStore=firebase.firestore(); 
 
GithubのDeveloper Settingに先ほどデプロイしたアプリのURLを入力してここにしたがってConsoleに入力し、Firebase側のリダイレクトURLをGithub側に入力します。

Loginコンポーネントは作ったので、LoginActionを作って、ReduxでConnectします。

action/index.js

import { firebaseAuth } from '../firebase'; 
 
export const loginWithGithub = () => dispatch => { 
  const provider=new firebaseAuth.GithubAuthProvider(); 
  firebaseAuth().signInWithPopup(provider) 
} 
containers/Login/index.js

import { connect } from 'react-redux'; 
import { loginWithGithub, signOut } from '../../actions'; 
import Login from '../../components/Login'; 
 
 
const mapDispatchToProps = dispatch => ({ 
  loginWithGithub: () => dispatch(loginWithGithub()), 
  signOut: () => dispatch(signOut()) 
}) 
export default connect( 
  null, 
  mapDispatchToProps 
)(Login) 
 
詳細はGithubを参考してください


2. To-DoのFireStoreへの保存

次はFirestoreを使います。

アプリの起動時にDBのTodoをリスナーセットと同時にFetchし、ActionでDBを変更し、リスナーが

動くことによりClient側が変更される構成にします

FireStoreの話も描こうか考えましたが、Firebaseアドベントカレンダーなどによいことがたくさん書いてあるので書きません

まずFetchAction,

FireStoreはNoSQLの木構造がcolletion, document, collectionとループしています

今回はTodos Collectionを作り、そこにFireStore自動生成IDのTodo Documentを作ります。

const fetchTodoSuccess = todos => { 
  return { 
    type: 'RECEIVE_TODO', 
    todos: todos 
  } 
} 
 
export const fetchTodos = () => dispatch => { 
  todosRef.onSnapshot((snapshot) => { 
    let todos=[]; 
    snapshot.docs.forEach((doc) => { 
      const todo = doc.data(); 
      todos.push({ 
        id: doc.id, 
        ...todo 
      }); 
    }) 
    dispatch(fetchTodoSuccess(todos)); 
  }) 
} 
 
export const addTodo = text => dispatch => { 
  todosRef.add({text:text, completed:false}); 
  return; 
} 
 
export const toggleTodo = (id, completed) => dispatch => { 
  todosRef.doc(id).update({completed: !completed}) 
  return; 
} 
詳細はレポジトリを確認してください。


おわりに

アドベントカレンダーが書かずに残っているのにとてもいきどおりをかんじたのでやっつけで更新しました。

やるといったことはやるようにしましょう()

コメント

このブログの人気の投稿

投稿時間:2021-06-17 22:08:45 RSSフィード2021-06-17 22:00 分まとめ(2089件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)