🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Cloud Firestore

Cloud Firestore は、自動スケーリングと高性能を実現し、アプリケーション開発を簡素化するように構築された NoSQLドキュメントデータベースです。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

3006閲覧

Githubカレンダーを実装したいがCannot read property 'toDate' of nullが発生する

moyong

総合スコア19

Cloud Firestore

Cloud Firestore は、自動スケーリングと高性能を実現し、アプリケーション開発を簡素化するように構築された NoSQLドキュメントデータベースです。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

1クリップ

投稿2021/03/16 05:50

実現したいこと

TypeError: Cannot read property 'toDate' of nullを解決したい。
イメージ説明

前提

Githubの草カレンダーをポートフォリオに実装したいです。
筋トレSNSアプリを作っていまして、firestoreからユーザーの筋トレ記録(簡単に言うと「何をどれだけやったか」です)を取得して配列の形でstateに詰め、react-calenderというライブラリに渡すことで実現したいと考えてます。
イメージ説明

発生している問題・エラーメッセージ

二枚目の写真の通り、データを取得して色塗りまではできたのですが、
データを登録するとき(二枚目の写真の左下の「Post」ボタンを押したとき)に一枚目のエラーが発生します。

エラー画面で更新すると、一枚目のように色塗りされていることが確認できます(エラー画面から正常な画面に移る)。
間違っているのがDateオブジェクトの扱い方なのか、useEffectの書き方なのか分からなくなってしまいました。

該当のソースコード

UserTsx

1import React, { useState, useEffect } from 'react' 2import { auth, db } from "../../firebase"; 3import { useSelector } from "react-redux"; 4import { selectUser } from "../../features/userSlice"; 5import { selectProfileUser } from "../../features/profileUserSlice"; 6import ExitToAppIcon from '@material-ui/icons/ExitToApp'; 7import { 8 Avatar, 9 createStyles, 10 makeStyles, 11 Theme, 12} from "@material-ui/core"; 13import CalendarHeatmap from "react-calendar-heatmap"; 14import "react-calendar-heatmap/dist/styles.css"; 15import ReactTooltip from "react-tooltip"; 16import "./User.tsx.scss"; 17 18const useStyles = makeStyles((theme: Theme) => 19 createStyles({ 20 large: { 21 width: theme.spacing(9), 22 height: theme.spacing(9), 23 }, 24 }), 25); 26interface Commit { 27 date: string; 28 count: number; 29} 30const User:React.FC = () => { 31 const classes = useStyles(); 32 const user = useSelector(selectUser); 33 const profileUser = useSelector(selectProfileUser); 34 const [ commits, setCommits ] = useState<Commit[]>([]); 35 const [ commitUser, setCommitUser ] = useState(""); 36 37 useEffect(() => { 38 // if (profileUser) { 39 // setCommitUser(profileUser.name); 40 // } else { 41 // setCommitUser(user.displayName) 42 // } 43 const fetchDate = async() => { 44 try{ 45 await db.collection("training_posts") 46 .where("username", "==", "たらお@redux難しい") 47 .onSnapshot((querySnapshot) => setCommits( 48 querySnapshot.docs.map((doc) => ({ 49 date: doc.data().timestamp.toDate(), 50 count: doc.data().training_array.length, 51 })) 52 )); 53 } catch(err) { 54 console.error(err); 55 } 56 } 57 fetchDate(); 58 }, []) 59 return ( 60 <div className="flex flex-col"> 61 <div className="flex items-center"> 62 <Avatar 63 data-testid="avatar" 64 className={classes.large} 65 src={profileUser.avatar 66 ? profileUser.avatar 67 : user.photoUrl 68 } 69 /> 70 <h3 data-testid="profileUsername" className="font-bold text-xl text-white ml-5"> 71 {profileUser.name 72 ? profileUser.name 73 : user.displayName 74 } 75 </h3> 76 <button 77 data-testid="signOut" 78 className="cursor-pointer bg-transparent border-none outline-none text-white" 79 onClick={async () => { 80 await auth.signOut(); 81 }} 82 > 83 <ExitToAppIcon/> 84 </button> 85 </div> 86 <div className="mt-5 text-whiteSmoke"> 87 <CalendarHeatmap 88 startDate={new Date(new Date().setDate(new Date().getDate() - 120))} 89 endDate={new Date()} 90 values={commits} 91 classForValue={(value) => { 92 if (!value) { 93 return "color-empty"; 94 } 95 return `color-scale-${value.count}`; 96 }} 97 tooltipDataAttrs={(value:any) => { 98 if (!value || !value.date) { 99 return null; 100 } 101 return { 102 "data-tip": `${value.date} has count: ${ 103 value.count 104 }`, 105 }; 106 }} 107 /> 108 <ReactTooltip/> 109 </div> 110 {/* <div> 111 {commits.map((cm) => ( 112 <> 113 <p>{cm.date}</p> 114 <p>{cm.count}</p> 115 </> 116 ))} 117 </div> */} 118 </div> 119 ) 120} 121 122export default User

イメージ説明

備考

react-calendar-heatmapのrepo

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hoshi-takanori

2021/03/16 08:05

timestamp が null みたいですけど…。console.log で doc.data() の内容を確認してみては? あと、toDate() するなら interface Commit の date の型は Date のような…。
moyong

2021/03/16 15:25

hoshi-takanoriさん、ありがとうございます。 返事が遅れてしまい申し訳ありません。 interfaceを修正して、useEffect内でconsole.logを呼ぶよう記述して記録をPostすると一部のドキュメントのtimestampがnilになっていることが確認できました。
guest

回答1

0

自己解決

こちらを参考に、ドキュメント作成時のtimestampの値を変更したところ、timestampがnilになる事態を避けることができました。

timestamp: firebase.firestore.FieldValue.serverTimestamp()

timestamp: firebase.firestore.Timestamp.now(),

に変更しました。

投稿2021/03/16 15:30

moyong

総合スコア19

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問