# #reactjs #firebase #google-cloud-firestore
#реагирует на #огневая база #google-облако-firestore
Вопрос:
Прямо сейчас для моего веб-приложения я пытаюсь использовать firebase для отображения данных из моей базы данных в мое приложение. Один из пользователей (пользователи-это коллекция в базе данных) имеет идентификатор QTKVV0WOBMhkq7Q6TPpDsGvprXf1. Идентификатор-это просто идентификатор пользователя (так что CurrentUser.uid). И у каждого пользователя есть набор привычек. Когда я жестко ввожу идентификатор QTKVV0WOBMhkq7Q6TPpDsGvprXf1 в путь, я могу отображать данные из своей базы данных в своем приложении на локальном хосте, но я хочу иметь возможность отображать данные любого пользователя независимо.
Я перепробовал столько способов, сколько мог, но, похоже, просто не могу этого понять. Есть какие-нибудь предложения? Я попытался создать переменную, содержащую текущий идентификатор пользователя.uid, но это не работает. Я пробовал делать и другие вещи, но все это заканчивалось ошибками…
Поэтому в идеале я хотел бы поменять середину пути в onSnapshot, чтобы он просто принимал текущий.uid
import React, { useEffect, useState } from "react"; import Habit from "./Habit"; import SearchBar from "./SearchBar"; import db, { useAuth } from "../firebase"; import { onSnapshot, collection } from "@firebase/firestore"; const HabitList = ({ mainSection, handleMainSection }) =gt; { // this initial state will be replaced with API request const [habits, setHabits] = useState([ // { name: "Sample habit 1", id: 1 }, // { name: "Sample habit 2", id: 2 }, // { name: "Sample habit 3", id: 3 }, ]); const currentUser = useAuth(); var currentUserPath; if(currentUser) { console.log('uid: ', currentUser.uid) currentUserPath=currentUser.uid; console.log('currentUser: ', currentUser); } useEffect( () =gt; onSnapshot(collection(db, `users/QTKVV0WOBMhkq7Q6TPpDsGvprXf1/user_habits`), (snapshot) =gt; setHabits(snapshot.docs.map((doc) =gt; doc.data())) //setHabits(snapshot.docs.map((doc) =gt; doc.data())); // make sure that setHabits works and sets snapshot to habits //console.log(habits); // habits should have the habits from firebase, not the initial habits we hardcoded ), [] ); return ( lt;div className="flex flex-col"gt; lt;SearchBar /gt; {habits.map(h =gt; ( lt;Habit habitName={h.name} handleMainSection={handleMainSection} key={h.id} /gt; ))} lt;/divgt; ); }; export default HabitList;
firebase.js (useAuth)
// Import the functions you need from the SDKs you need import { useEffect, useState } from "react"; import { initializeApp } from "firebase/app"; import { getAuth, createUserWithEmailAndPassword, signInWithEmailAndPassword, onAuthStateChanged } from "firebase/auth"; import { getFirestore } from "firebase/firestore"; import { doc, setDoc } from "firebase/firestore"; import { v4 as uuidv4 } from "uuid"; // TODO: Add SDKs for Firebase products that you want to use // https://firebase.google.com/docs/web/setup#available-libraries // Your web app's Firebase configuration const firebaseConfig = { apiKey: "AIzaSyBN30k6RivLOuz7KToi_uD8V5s5cmyD9RM", authDomain: "auth-development-62c42.firebaseapp.com", projectId: "auth-development-62c42", storageBucket: "auth-development-62c42.appspot.com", messagingSenderId: "414005826367", appId: "1:414005826367:web:7b987851735426ebedf98a" }; // Initialize Firebase const app = initializeApp(firebaseConfig); const auth = getAuth(); export function signup(email, password) { return createUserWithEmailAndPassword(auth, email, password); } export function login(email, password) { return signInWithEmailAndPassword(auth, email, password); } // eventually write a logout function export async function sendHabitToFirestore(uidPath, habitName) { const db = getFirestore(); const habitId = uuidv4(); const pathDocRef = doc(db, "users", uidPath, "user_habits", habitId); await setDoc(pathDocRef, { name: habitName, id: habitId }); } export function useAuth() { const [currentUser, setCurrentUser ] = useState(); useEffect(() =gt; { const unsub = onAuthStateChanged(auth, user =gt; setCurrentUser(user)); return unsub; }, []) return currentUser; } export default getFirestore();
Ошибка:
Failed to compile ./src/components/HabitList.jsx SyntaxError: C:UsersjojocDesktoplocal_devhabitudesrccomponentsHabitList.jsx: Unexpected token (37:6) 35 | setHabits(newHabits); // consider using snapshot.docChanges() in later renders for efficiency 36 | console.log("New version of habits found!", newHabits); // note: habits isn't updated straight away, so we use the array passed to setHabits gt; 37 | ), | ^ 38 | (error) =gt; { 39 | // TODO: Handle errors! 40 | } This error occurred during the build time and cannot be dismissed.
Ответ №1:
В зависимости от вашей реализации useAuth
, currentUser
может быть кратко null
, что означает, что при первом рендеринге вы useEffect
подключаетесь к users/undefined/user_habits
вместо ожидаемого идентификатора пользователя. Поскольку ваш useEffect
прослушиватель не прослушивает изменения currentUser
, он никогда не будет вызван снова с соответствующим идентификатором пользователя после проверки сеанса.
useEffect(() =gt; { if (currentUser == null) { // signed out/not ready // if habits is already empty, don't trigger a rerender setHabits(habits.length === 0 ? habits : []); return; } const userDocRef = collection(db, `users/${currentUser.uid}/user_habits`); return onSnapshot( userColRef, (snapshot) =gt; { const newHabits = snapshot.docs.map((doc) =gt; doc.data()); setHabits(newHabits); // consider using snapshot.docChanges() in later renders for efficiency console.log("New version of habits found!", newHabits); // note: habits isn't updated straight away, so we use the array passed to setHabits }, (error) =gt; { // TODO: Handle errors! } ); }, [currentUser]); // rerun if currentUser changes (e.g. validated, signed in/out)
Комментарии:
1. я попытался скопировать и вставить его в свой код, но он не смог скомпилироваться. я думаю, что это связано с некоторыми синтаксическими ошибками? я обновлю свой пост, чтобы включить в него ошибку.
2. Я также добавил реализацию useAuth на случай, если это будет более полезно, хотя я согласен, что слушатель useEffect, вероятно, не видит изменений в текущем пользователе, поэтому я получаю пользователей/неопределенных/пользователей.
3. На самом деле nvm, я исправил некоторые детали, но в остальном это работает, я верю, спасибо!
4. @outofthegravity Моя вина. Это было
)
вместо}
«а». Рад помочь.