yucatio@システムエンジニア

趣味で作ったものいろいろ

タスクの書き込みパスの変更 (STEP 2 : ユーザ認証を行なって、自分だけが読み込めて書き込めるタスク管理アプリを作成する - React + Redux + Firebase チュートリアル)

★前回の記事

yucatio.hatenablog.com

タスクの書き込みパスを変更します。

todo actionの変更

書き込みパスを、todos/からtodos/${uid}に変更します。念のため、uidが定義されていない時はエラーを出すようにします。

src/actions/index.js

export const NOT_AUTHENTICATED_ON_TODO_ACTION = 'NOT_AUTHENTICATED_ON_TODO_ACTION';  // 追加

src/actions/todoActions.js

import {ADD_TODO_REQUEST, ADD_TODO_SUCCESS, ADD_TODO_ERROR,
  TOGGLE_TODO_REQUEST, TOGGLE_TODO_SUCCESS, TOGGLE_TODO_ERROR,
  NOT_AUTHENTICATED_ON_TODO_ACTION}  //  追加
   from './'

// 中略

const notAuthenticatedOnTodoAction = () => ({
  type: NOT_AUTHENTICATED_ON_TODO_ACTION
})

export const addTodo = (uid, text) => {  // #1
  return (dispatch, getState, {getFirebase}) => {
    if (!uid) {  // #2
      dispatch(notAuthenticatedOnTodoAction());
      return;
    }
    dispatch(addTodoRequest());
    const firebase = getFirebase();
    firebase.push(`todos/${uid}`, {completed: false, text})   // #3
    // 中略
  }
}

export const toggleTodo = (uid, id) => {  // #4
  return (dispatch, getState, {getFirebase}) => {
    if (!uid) {  // #5
      dispatch(notAuthenticatedOnTodoAction());
      return;
    }
    const firebase = getFirebase();
    const state = getState();
    const todo = state.firebase.data.todos[uid][id];  // #6
    dispatch(toggleTodoRequest(todo.text, !todo.completed));
    firebase.update(`todos/${uid}/${id}`, {completed: ! todo.completed})  // #7
    // 中略
  }
}
  • addTodoの引数にuidを追加します(#1)。
  • uidが未定義などの場合、エラーを画面に表示するように、dispatchします(#2, #5)。
  • 書き込みパスをtodos/${uid}に変更します(#3)。
  • toggleTodoの引数にuidを追加します(#4)。
  • 選択したtodoのデータの保存場所を変更します(#6)。
  • 書き込みを行うパスを、todos/${id}から、todos/${uid}/${id}に変更します(#7)。

reducerの変更

NOT_AUTHENTICATED_ON_TODO_ACTIONに対応するコードを追加します。

src/reducers/todos.js

import {ADD_TODO_REQUEST, ADD_TODO_SUCCESS, ADD_TODO_ERROR,
  TOGGLE_TODO_REQUEST, TOGGLE_TODO_SUCCESS, TOGGLE_TODO_ERROR,
  NOT_AUTHENTICATED_ON_TODO_ACTION}  // 追加
   from '../actions/'

// 中略

const todos = (state = {}, action) => {
  switch (action.type) {
    // 中略
    case NOT_AUTHENTICATED_ON_TODO_ACTION :  // 追加
      return {...state, notice: 'タスクを追加・変更するにはログインしてください'}
    // 中略
  }
}

componentの変更

actionにuidを渡すように、componentを変更します。

src/components/TodoComponent

let TodoComponent = ({uid, authenticating, authenticated}) => {
  // 中略
  return (
    <div>
      <AddTodo uid={uid} />  {/* #1 */}
      <NoticeForTodo />
      <VisibleTodoList uid={uid} />
      <Footer />
    </div>
  )
}
  • AddTodouidを渡します(#1)。

src/containers/AddTodo.js

// 前略
import PropTypes from 'prop-types'  // #1

let AddTodo = ({ uid, dispatch }) => {  // #2
  // 中略
  return (
    <div>
      <form
        onSubmit={ e => {
          // 中略
          dispatch(addTodo(uid, input.value))  // #3
          // 中略
        }}
      >
  // 中略
}

AddTodo.propTypes = {  // #4
  uid: PropTypes.string.isRequired,
}
  • PropTypesをimportします(#1)。
  • AddTodoコンポーネントの引数に、uidを追加します(#2)。
  • addTodoの引数にuidを追加します(#3)。
  • uidに対するpropTypesを設定します(#4)。

src/visibleTodoList.js

const mapDispatchToProps = (dispatch, {uid}) => {  // #1
  return {
    onTodoClick: (id) => {
      dispatch(toggleTodo(uid, id))  // #2
    }
  }
}
  • ownPropsからuidを受け取ります(#1)。
  • toggleTodoの引数にuidを追加します(#2)。

動作確認

ログインします。

f:id:yucatio:20181003115453p:plain

タスクを追加します。

f:id:yucatio:20181004151052p:plain

追加できました。

タスクをさらに追加して、タスク完了フラグを切り替えます。

f:id:yucatio:20181004224626p:plain

うまく動きました。

ログアウトしてから、別ユーザでログインします。

f:id:yucatio:20181004224422p:plain

f:id:yucatio:20181004224928p:plain

タスク追加、タスク完了フラグの切り替えが動作しました。

データベースも確認します。

f:id:yucatio:20181004225938p:plain

ユーザごとにタスクが作成されています。STEP 1で作成したタスクは削除してしまいましょう。

以上でユーザ認証を行なって、自分だけが読み込めて書き込めるタスク管理アプリが完成しました!おめでとうございます!

★次回の記事

yucatio.hatenablog.com

★目次

yucatio.hatenablog.com