shio-max
@shio-max (Riooo)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

firestoreのtimestampを取得し、ローカルstateに渡したい。

解決したいこと   

react,redux,firebaseで todoアプリを作成しています。
こちらを参考にしてます。

todoリストの新規作成は実装済みでして、そのデータを取得して、編集&更新機能を実装しているのですが、
1つ、ローカルstateにfirestoreから取得したdataのselectedDateを渡しても、ページの表示では、今日の日付が表示されてしまいます。 
その他itemsとnoteは無事 データを取得し表示できてます。
スクリーンショット 2021-05-01 午後9.56.23.png

[追記:warning:]
色々試してみたところ、firestoreで保存されてるtimestamp型のselectedDateのデータを取得するところがうまくいってないようです。toDate()でJSのDateオブジェクトに変換したいのですが、selectedDate of undefinedになります。 どうすればtimestamp型のデータを変換してstateに渡せますか?

該当するソースコード   

templates/CreateTaskList.jsx

const CreateTaskList = () => {
  const classes = useStyles();
  const dispatch = useDispatch();
  const selector = useSelector((state) => state);
  const uid = getUserId(selector);

  let id = window.location.pathname.split("task/create")[1];
  if (id !== "") {
    id = id.split("/")[1];
  }

  const [selectedDate, setSelectedDate] = useState(new Date());
  const [items, setItems] = useState([]);
  const [note, setNote] = useState("");



  //編集のとき
  useEffect(() => {
    if (id !== "") {
      db.collection("users")
        .doc(uid)
        .collection("tasklist")
        .doc(id)
        .get()
        .then((snapshot) => {
          const data = snapshot.data();
          console.log(data);
          const selectedDate = data.selectedDate.toDate(); // ←ここ
          setSelectedDate(selectedDate);
          setItems(data.items);
          setNote(data.note);
        });
    }
  }, [uid, id]);
  return (
    省略
              <DatePicker
                selectedDate={selectedDate}
                setSelectedDate={setSelectedDate}
              />

              <SetTodoItem items={items} setItems={setItems} />


              <TextInput
                fullWidth={true}
                label={"NOTE"}
                margin={"normal"}
                multiline={true}
                required={false}
                rows={5}
                value={note}
                variant={"outlined"}
                type={"text"}
                onChange={inputNote}
              />


          <Button
            variant="contained"
            color="secondary"
            className={classes.button}
            startIcon={<AddIcon />}
            onClick={() => {
              dispatch(saveTaskList(selectedDate, items, note));
            }}
          >
            作業リストを保存
          </Button>

  );
};

export default CreateTaskList;

console.log(data)
スクリーンショット 2021-05-03 午後11.43.39.png

components/DatePicker.jsx

import "date-fns";
import React from "react";
import DateFnsUtils from "@date-io/date-fns";
import {
  MuiPickersUtilsProvider,
  KeyboardDatePicker,
} from "@material-ui/pickers";

const DatePicker = (props) => {
  const handleDateChange = (date) => {
    props.setSelectedDate(date);
  };
  return (
    <MuiPickersUtilsProvider utils={DateFnsUtils}>
      <KeyboardDatePicker
        margin="normal"
        id="date-picker-dialog"
        label="日付"
        format="MM/dd/yyyy"
        value={props.selectedDate}
        onChange={handleDateChange}
        KeyboardButtonProps={{
          "aria-label": "change date",
        }}
      />
    </MuiPickersUtilsProvider>
  );
};
export default DatePicker;

operation.js
export const saveTaskList = (selectedDate, items, note) => {
  return async (dispatch, getState) => {
    const timestamp = FirebaseTimestamp.now();
//(export const FirebaseTimestamp = firebase.firestore.Timestamp;)を別で設定
    const uid = getState().users.uid;
    const tasklistRef = db
      .collection("users")
      .doc(uid)
      .collection("tasklist")
      .doc();

    const data = {
      selectedDate: selectedDate,
      items: items,
      note: note,
    };

    const id = tasklistRef.id;
    data.created_at = timestamp;
    data.id = id;

    return db
      .collection("users")
      .doc(uid)
      .collection("tasklist")
      .doc(id)
      .set(data)
      .then(() => {
        dispatch(push("/"));
      })
      .catch((error) => {
        alert("データの保存に失敗しました。");

        const errorMessage = error.message;
        console.log(errorMessage);
      });
  };
};

[追記:warning::warning:] 変更後

.then((snapshot) => {
          const data = snapshot.data();
          console.log(data);
          console.log(data.selectedDate);
          console.log(data.updated_at.toDate());
          const selectedDate = data.selectedDate.toDate();
          setSelectedDate(selectedDate);

スクリーンショット 2021-05-05 午前0.25.19.png

firestoreでは selectedDateはtimestamp型で保存されているのが確認できます。
スクリーンショット 2021-05-05 午前0.00.56.png

アドバイス、解決策お待ちしております!!

0

1Answer

console.log(data) の結果を見ると、data の直下に selectedDate があるようです。

          const selectedDate = data.selectedDate.toDate();

ではどうでしょうか?

0Like

Comments

  1. @shio-max

    Questioner

    それだと、selectedDate of undefined になります。
  2. 掲示のソースの該当箇所で
    `data.timestamp.selectedDate` でも `selectedDate of undefined` がでて
    `data.selectedDate` にしても `selectedDate of undefined` がでるということですか?

    それはありえないように思います。
    もしかしたら、違う場所でエラーが出ているのではないでしょうか?
    (あるいは、挙動が変わったということですが)

    data.selectedDate で `selectedDate of undefined` がでるなら、それは data が undefined だった、ということです。

    そうであれば、data.timestamp.selectedDate は `timestamp of undefined` になるはずです。

  3. @shio-max

    Questioner

    部分部分で変更し、ログ出力の繰り返しで、  XX of undefined の XX がその時々で変わってて、 undefined になってたみたいです。今現在の状態は、ログで data.selectedDate の確認はできていますが、今度は not a functionのエラーがでてます。(質問に追記してます)
    すみません、ややこしくしてしまって、、

Your answer might help someone💌