LoginSignup
henrry-sakurazaka
@henrry-sakurazaka

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Firestoreにデータが書き込めない、取得できない。

解決したいこと

ここに解決したい内容を記載してください。

リマインダーアプリを制作してます。
フロントエンドをReact、バックエンドをFirebase
Firestoreで実装中です。

発生している問題・エラー

フォームを作成してinputタグにクリックハンドラを
仕込んでuseReducerでdispatchしてます。Firestore用
にもう一つ関数を用意して、そちらでFirestoreに同じ
タスクを書き込んで取得したいのですが
関数が機能しません。console.log()が出力されません。
何が問題なのでしょうか?
ご教授お願いします。

出ているエラーメッセージを入力

エラーは出ていません。

または、問題・エラーが起きている画像をここにドラッグアンドドロップ

スクリーンショット 2024-04-20 8.25.15.png

該当するソースコード

言語名


ソースコードを入力

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Firestoreのセキュリティルール(開発中のみ)

// rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// 全てのドキュメントへの読み書きを許可する
match /{document=**} {
allow read, write: if true;
}
}
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Formコンポーネント


import React, { useEffect } from "react";
import { useState } from "react";
import { useDispatchTodos , useTodos , FirestoreContext } from "../context/TodoContext";
import { collection, setDoc, addDoc, doc, deleteDoc, updateDoc, getDocs, onSnapshot } from 'firebase/firestore';
import { db, app, firestore} from "../firebase";
import { getFirestore } from 'firebase/firestore';
import firebase from "firebase/app"; // firebaseモジュールをインポート


const Form = () => {
    
    const dispatch = useDispatchTodos();
    const { todos, AddTodos, fetchTodos, 
            enteredTodo, setEnteredTodo,
            fireTodo, setFireTodo
    } = useTodos();
   
    const addTodo = () => {
        const newTodo = {
            id: Math.floor(Math.random() * 1e5),
            content: fireTodo,
        };
        dispatch({ type: "todo/add", todo: newTodo, editing: false });
        setFireTodo("");
        AddTodos();
    }

    const allComplete = () => {
        const neoTodo = {
            completed: true
        };
        dispatch({type: "todo/reset", todo: neoTodo, editing: false });   
    }

    // useEffect(() => {
    //     fetchTodos(firestore, dispatch);
    // })

    // const addTask = () => {
    //     const neoTodo7 = {
    //         id: Math.floor(Math.random() * 1e5),
    //         content: enteredTodo,
    //     };
    //     dispatch({type: "SET_TODOS", todo: neoTodo7, editing: false});
    //     setEnteredTodo("");
    // }
    
    return(
        <div>  
            <input type="text" value={fireTodo} id="task" name="task" 
            onChange={(e) => setFireTodo(e.target.value)}/>
                <div className="flex-box">
                    <button className="add" onClick={() => addTodo()}>
                        <div className="plus">
                            <span className="gif1"></span>
                            <span className="gif2"></span>
                        </div>
                    </button>
                    <button className="reset2" onClick={() => allComplete()}>
                        <div className="reset">
                            <img src="/icon_007476_32.png" alt="reset"></img>
                        </div>
                    </button>
                </div>       
        </div>

    );
       
}

export default Form;





//TodoContext






import React, { useMemo } from "react";
import { createContext, useContext, useReducer, useState, useEffect } from "react";
import { db, app, firestore} from "../firebase";
import { initializeApp } from "firebase/app";
import { getFirestore } from 'firebase/firestore';
import { getDatabase , ref, get, onValue } from "firebase/database";
import { collection, setDoc, addDoc, doc, deleteDoc, updateDoc, getDoc, onSnapshot } from 'firebase/firestore';
import firebase from "firebase/app"; // firebaseモジュールをインポート
import firebaseConfig from "../firebase";
// import 'firebase/firestore'; // Firestoreをインポート
// import 'firebase/database'; // Realtime Databaseをインポー

 const TodoContext = createContext();
 const TodoDispatchContext = createContext();
 
 const todoReducer = (todos, action) => {

    switch (action.type) {
      case 'todo/add':
        return [...todos, action.todo];
      case 'todo/delete':
        return todos.filter(todo => todo.id !== action.todo.id);
      case 'todo/update':
        return todos.map(_todo =>
          _todo.id === action.todo.id ? { ..._todo, ...action.todo } : { ..._todo }
        );
      case 'todo/complete':
        return todos.map(todo =>
          todo.id === action.todo.id ? { ...todo, ...action.todo } : { ...todo }
        );
      case 'todo/reset':
        return todos.filter(todo => null); // ここは正しくないので修正が必要

      case 'todo/reserve':
        return todos.map(_todo =>
          _todo.id === action.todo.id
            ? { ..._todo, editingLock: true }
            : { ..._todo, editingLock: false }
        );
      case 'todo/reserveColor':
        return todos.map(_todo =>
          _todo.editingDateTime
            ? { ..._todo, editingColor: true }
            : { ..._todo, editingColor: false }
        );
      case 'todo/editingDateTime':
        return todos.map(_todo =>
          _todo.editingLock
            ? { ..._todo, editingDateTime: true }
            : { ..._todo, editingDateTime: false }
        );
      case 'SET_TODOS':
        return action.payload;

      default: 
        return todos;
    }
  };

 

 const TodoProvider = ({ children }) => {
  const todoList = useMemo(() => [
    {
      id: 1,
      content: "Make a restaurant reservation",
      editing: false,
      completed: false,
      reserve: false,
      editingLock: false,
      editingColor: false,
      editingDateTime: false
    },
    {
      id: 2,
      content: "send a letter",
      editing: false,
      completed: false,
      reserve: false,
      editingLock: false,
      editingColor: false,
      editingDateTime: false
    },
    {
      id: 3,
      content: "buy flowers",
      editing: false,
      completed: false,
      reserve: false,
      editingLock: false,
      editingColor: false,
      editingDateTime: false
    },
  ], []);
  

 
    const [ todos, dispatch ] = useReducer(todoReducer, todoList);
    const [modalOpen, setModalOpen ] = useState(false);
    const [selectedDate, setSelectedDate] = useState(new Date());
    const [isDateSet, setIsDateSet] = useState(false);
    const [isDateChecked, setIsDateChecked] = useState(false);
    const [isTimeChecked, setIsTimeChecked] = useState(false);
    const [isContainerDateCheck, setContainerDateCheck] = useState(false);
    const [isContainerTimeCheck, setContainerTimeCheck] = useState(false);
    const [selectedTime, setSelectedTime] = useState("12:00");
    const [isTimeSet, setIsTimeSet] = useState(false);
    const [displayTimePicker, setDisplayTimePicker] = useState(false);
    const [displayDatePicker, setDisplayDatePicker] = useState(false);
    const [loading, setLoading] = useState(true);
    const [enteredTodo, setEnteredTodo] = useState(""); 
    const [fireTodo, setFireTodo] = useState("");

   
  
      const firebaseApp = initializeApp(firebaseConfig);
      const firestore = getFirestore(firebaseApp);
  
      const newTask = useMemo(() => ({
            title: "newTask",
            description: "todoリストの保存",
            type: "string",
            content: "ユーザーが入力したタスク",
            editing: false,
            completed: false,
            reserve: false,
            editingLock: false,
            editingColor: false,
            editingDateTime: "12:00"
          }), []

  //この関数が上手く機能しません ☟

   
         useEffect(() => {
            const fetchData = async () => {
              const todoCollectionRef = collection(firestore, 'todoList');
            
              try { 
                await addDoc(todoCollectionRef, newTask); 
                const docRef = doc(firestore, 'content')   
                const snapshot = await getDoc(docRef);
                if(snapshot.exists()) {
                  console.log(snapshot.data()) // <- 修正
                }
                const todosData = [snapshot.data()]; // <- 修正
                dispatch({ type: 'todo/add', payload: todosData });
                console.log('Todos added to Firestore Successfully');
            
                const unsubscribe = onSnapshot(todoCollectionRef, (snapshot) => {
                  const todosData = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
                  dispatch({ type: 'SET_TODOS', payload: todosData });
                  console.log('Todos updated in Firestore');
                });
                
                return () => unsubscribe();
              } catch (error) {
                console.error('Error adding todoList to Firestore:', error);
              }
            }; 
            fetchData();
          }, [firestore, newTask, todoList]);
             
    
    
      
        //Todo追加
        const AddTodos = () => {
          try {
            // マップされた todoList を Firestore に追加
            (todoList.map(async todo => {    
              const todoCollection = collection(firestore, 'todoList');
              const newTodoRef =  addDoc(todoCollection, { content: todo.content, completed: false });
              const dataTodo = { id: newTodoRef.id, content: todo.content, completed: false }; 
              dispatch({ type: 'todo/add', todo: dataTodo, editing: false });
            }));

            console.log('Todos added to Firestore successfully');
          } catch (error) {
            console.error('Error adding todoList to Firestore:', error);
          }
        };





  
        


      // Todo削除
      const deleteTodo = async todoId => {
        const todoDocRef = doc(firestore, 'todoList', todoId);
        await deleteDoc(todoDocRef);
        dispatch({ type: 'todo/delete', payload: todoId });
      };
    
      // Todo更新
      const updateTodo = async (todoId, updatedFields) => {
        const todoDocRef = doc(firestore, 'todoList', todoId);
        await updateDoc(todoDocRef, updatedFields);
        dispatch({ type: 'todo/update', payload: { id: todoId, updatedFields } });
      };
      // Todoリセット
      const resetTodo = async (todoId, updatedFields) => {
        const todoDocRef = doc(firestore, 'todoList', todoId);
        await updateDoc(todoDocRef, updatedFields);
        dispatch({ type: 'todo/reset', payload: { id: todoId, updatedFields } });
      };
      // タイマー予約
      const reserveTodo = async (todoId, updatedFields) => {
        const todoDocRef = doc(firestore, 'todoList', todoId);
        await updateDoc(todoDocRef, updatedFields);
        dispatch({ type: 'todo/reserve', payload: { id: todoId, updatedFields } });
      };
      // Todo予約色
      const reserveColor = async (todoId, updatedFields) => {
        const todoDocRef = doc(firestore, 'todoList', todoId);
        await updateDoc(todoDocRef, updatedFields);
        dispatch({ type: 'todo/reserveColor', payload: { id: todoId, updatedFields } });
      };
      // Todo日時編集
      const editingDateTime = async (todoId, updatedFields) => {
        const todoDocRef = doc(firestore, 'todoList', todoId);
        await updateDoc(todoDocRef, updatedFields);
        dispatch({ type: 'todo/editingDateTime', payload: { id: todoId, updatedFields } });
      };
    
    const handleDateChange = (date) => {
        setSelectedDate(date);
        setIsDateSet(true);
        console.log(selectedDate)
    }

    const handleTimeChange = (event) => {    
        setSelectedTime(event.target.value);
        setIsTimeSet(true)
        console.log(selectedTime)
      };
    
    // console.log(selectedDate)
    // console.log(selectedTime)
    return (
        <TodoContext.Provider value=
            {{ todos, handleDateChange, 
            isDateChecked, setIsDateChecked, isTimeChecked , setIsTimeChecked, 
            isContainerTimeCheck, setContainerTimeCheck, isContainerDateCheck, 
            setContainerDateCheck, modalOpen, setModalOpen, selectedDate, setSelectedDate,
            handleTimeChange, selectedTime, setSelectedTime,displayTimePicker, setDisplayTimePicker,
            displayDatePicker, setDisplayDatePicker, isDateSet, setIsDateSet, isTimeSet, setIsTimeSet,
            AddTodos, enteredTodo, setEnteredTodo, fireTodo, setFireTodo

            }}>
              
          <TodoDispatchContext.Provider value={dispatch}>    
              {children}   
          </TodoDispatchContext.Provider>
       </TodoContext.Provider>
    )

 }

 const useTodos = () => useContext(TodoContext);
 const useDispatchTodos = () => useContext(TodoDispatchContext);
 
 export { useTodos , useDispatchTodos , TodoProvider, getDoc };

自分で試したこと

ここに問題・エラーに対して試したことを記載してください。

FirebaseSDKの確認、Firebaseの初期化、Firestoreの初期化、それぞれのエクスポート、インポート
FireStoreのセキュリティルールの確認。

開発ツールでのデバッグ

0

No Answers yet.

Your answer might help someone💌