反应/Firebase。如何在项目中保存更新的数据?

2024-05-26

当我尝试更改数据时 - 更改正在进入我的 Firestore 数据库,没关系,但是当我重新加载页面或注销并尝试再次登录时 - 用户数据不会出现在我的项目中,但也会出现存储在我的Firestore Database。即使重新加载页面后,如何保存并显示项目中的用户数据?

这是我的代码

    const [email, setEmail] = useState('')
    const [phone, setPhone] = useState('')
    const [language, setLanguage] = useState('')
    const [valute, setValute] = useState('')
    const [instagram, setInstagram] = useState('')
   

    const {user} = UserAuth()


    const createUser = (email, password) => {
        createUserWithEmailAndPassword(auth, email, password)
        .then((userCredential) => {
            const user = userCredential.user;
            const uid = user.uid;
            setDoc(doc(db, 'users', uid), {
                email: email,
                name: name,
                password: password,
                phone: phone,
                language: language,
                instagram: instagram,
                valute: valute,
            });
          })
          .catch((error) => {
            const errorCode = error.code;
            const errorMessage = error.message;
            // ..
          });
    }

    const updatePerson = async(email, phone, language, valute, instagram, name, ) => {
      await updateDoc(doc(db, 'users', user.uid), {email, phone, language, valute, instagram, name})
    }

    <input type="text" placeholder={name || user.displayName || user.email || user.phoneNumber} className='form-control' onChange={(e) => setName(e.target.value)}/>
    <input type="text" placeholder={instagram} className='form-control' onChange={(e) => setInstagram(e.target.value)}/>
    <input type="text" placeholder={email} className='form-control' onChange={(e) => setEmail(e.target.value)}/>
    <input type="text" placeholder={phone} className='form-control' onChange={(e) => setPhone(e.target.value)}/>
    <input type="text" placeholder={language} className='form-control' onChange={(e) => setLanguage(e.target.value)}/>
    <input type="text" placeholder={valute} className='form-control' onChange={(e) => setValute(e.target.value)}/>

我为此目的使用自定义挂钩。这是非常可重用的,我可以同时加载多个(特定)用户(或其他任何内容)。

useUserData.jsx

import { useEffect, useState } from "react";
import { doc, onSnapshot } from "firebase/firestore";
import { db } from "../firebase";


export function useUserData(userId) {
  const [userData, setUserData] = useState(undefined); // undefined means not loaded

  useEffect(() => {
    if (!userId) {
      // null or undefined is passed
      setUserData(undefined);
      return; 
    }
    const unsubscribe = onSnapshot(doc(db, "users", userId), (doc) => {
      if (doc.exists()) {
        setUserData(doc.data()); // found and setting a user
      } else {
        setUserData(null); // null means user not found in users collection
      }
    });

    return () => unsubscribe();
  }, [userId]);

  return userData;
}

用法和附加解释和示例

import React, { useState, useCallback, useEffect } from "react"
import useAuthContext from "../../Context/AuthContext";
import { useUserData } from "../../Hooks/useUserData";

export function Home(props) {
  const {user, updateData} = useAuthContext();

  // NOTE: Do not destructure in this way due to it will cause an exception for null and undefined values
  // const {firstName, lastName} = useUserData(user?.uid); 

  const userData = useUserData(user?.uid); // user might be undefined, so ? is used. Null will be passed but hook will work

  // I prefer storing form data in this way, look at handleChanges function
  // Important: this approach relies on input "name" attribute, it should match
  const [formData, setFormData] = useState({
    firstName: "",
    lastName: ""
  });

  // Just to update the existing doc.
  const updatePersonSubmit = useCallback(async (evt) => {
    evt.preventDefault();
    await updateData(formData.firstName, formData.lastName);
  }, [updateData, formData]);

  // In setter you can get previous (current) value
  // this function that is passed as a parameter should return new object to set
  // new object consists of all ...prev fields it had
  // and one field is overriden by key (name) and will have a new value here
  const handleChange = useCallback((evt) => {
    setFormData(prev => ({...prev, [evt.target.name]: evt.target.value}));
  }, []);

  // listen to the userData updates and update the inputs
  // || prev.XXX is used due to data in userData can be null or undefined
  // inputs in React expects empty strings for bindings, nulls or undefined will
  // break everything, so using old value if any (initialized with "")
  useEffect(() => {
    setFormData(prev => ({
      ...prev,
      firstName: userData?.firstName || prev.firstName,
      lastName: userData?.lastName || prev.lastName
    }));
  }, [userData])

  return (
    <div className="container-fluid">
      {user && (
        <form>
          <p>Those fields are NOT in firestore, they needs to be set/updated with auth functions, not so easy here</p>
          <p>displayName: {user.displayName || "null"}</p>
          <p>email: {user.email || "null"}</p>
          <p>phoneNumber: {user.phoneNumber || "null"}</p>
        </form>
      )}
      <br/>
      <br/>
      <form onSubmit={updatePersonSubmit}>
        <p>Those fields are in firestore, they can be set/updated with firestore setDoc or updateDoc</p>

        <input name="firstName" type="text" placeholder={"firstName"} className='form-control'
               value={formData.firstName} onChange={handleChange}/>

        <input name="lastName" type="text" placeholder={"lastName"} className='form-control'
               value={formData.lastName} onChange={handleChange}/>

        <button type="submit">Save</button>
      </form>
    </div>
  )
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

反应/Firebase。如何在项目中保存更新的数据? 的相关文章

随机推荐

  • SQL Server 2005 中的计数(*) 与计数(Id)

    我使用 SQLCOUNT函数获取表中的总数或行数 以下两种说法有什么区别吗 SELECT COUNT FROM Table and SELECT COUNT TableId FROM Table 另外 在性能和执行时间方面有什么区别吗 Th
  • 设置 MySQL 触发器

    我听说过有关触发器的事情 我有几个问题 什么是触发器 我该如何设置它们 除了典型的 SQL 内容之外 是否还应该采取任何预防措施 触发器允许您在发生某些事件 例如 插入表 时在数据库中执行某个功能 我无法具体评论mysql 注意事项 触发器
  • 在字符串数组中查找下一个可用日期

    我一直在尝试找出如何根据当前日期获取下一个可用日期 即 如果今天是星期五 则在数组中搜索下一个最近的日期 例如数组值为 1 星期一 2 星期二 4 星期四 6 星期六 那么我的第二天应该是星期六 这是我尝试过的 Here i ll get
  • RecyclerView 上的删除按钮删除了错误的项目

    我正在使用 Firestore 适配器RecyclerView我在使用 删除 按钮时遇到问题 当我按下它时 它会删除错误的项目 而不是我想要的项目 这是我的按钮内部的代码onBindViewHolder protected void onB
  • 了解单目标迷宫的 A* 启发式

    我有一个像下面这样的迷宫 P
  • 传说在北卡罗来纳州地理地图上消失?

    我正在使用 R 编程语言 使用北卡罗来纳州的内置地图 我生成了 3 个随机变量 收入 孩子数量 体重 然后为此数据创建了地图 使用 传单 库 通过循环 library sf library mapview library leaflet l
  • jQuery Mobile 1.4.0:动态更改页面的标题和标题

    动态更改 jQuery Mobile 1 4 0 页面的标题 data role header 和 title 的正确方法是什么 添加方法有很多种toolbars 页眉 页脚 动态 此外 jQuery Mobile 1 4 提供intern
  • 检测堆栈已满

    在编写 C 代码时 我了解到使用堆栈来存储内存是一个好主意 但最近我遇到了一个问题 我有一个实验 其代码如下所示 void fun const unsigned int N float data 1 N N float data 2 N N
  • python:将base64编码的png图像转换为jpg

    我想使用 python 将一些 base64 编码的 png 图像转换为 jpg 我知道如何从 Base64 解码回原始 import base64 pngraw base64 decodestring png b64text 但现在我怎样
  • 土耳其语字符显示不正确[重复]

    这个问题在这里已经有答案了 MySql 数据库使用 utf 8 编码 数据存储正确 我使用 set name utf8 查询来确保调用的数据是 utf 8 编码 只要标头字符集是 utf 8 数据库中的所有变量都可以正常工作 但静态html
  • 无需发送消息即可获取 GCM 规范注册 ID

    我在使用 GCM 的应用程序时遇到问题 情况如下 该应用程序已安装 应用程序调用 GCM 注册方法获取注册 ID RID 1 该应用程序已卸载 再次安装该应用程序 应用程序再次调用 GCM 注册方法 获取注册 ID RID 2 在第 5 步
  • 如何在张量流中使用带有估计器的衰减学习率?

    我正在尝试将 LinearClassifier 与具有衰减学习率的 GradientDescentOptimizer 一起使用 My code def main load data features np load data feature
  • Wordpress/Woocommerce:以编程方式创建订单后,我还想以编程方式发送发票...如何?

    所以 我的网站涉及一个预订系统 流程如下 客人选择预订产品的日期 地点 提交请求后 系统会向主机发送一条消息以供审核 如果接受 我希望订单由客人支付 我的问题在这里 我已成功创建订单 理想情况下 我希望能够将客人发送到他们的 购物车 页面
  • 没有窗口的 GetFontUnicodeRanges

    有机会打电话吗GetFontUnicodeRanges没有窗户 例如 它可能是不允许与桌面交互的 Windows 服务 目前我正在使用控制台应用程序对此进行测试 program UnicodeConsoleOutput APPTYPE CO
  • 对 HashSet 进行子类化,以便在另一个集合中使用时始终使用某个 IEqualityComparer

    我想子类化HashSet
  • C++ 中的垃圾收集——为什么?

    我不断听到人们抱怨 C 没有垃圾回收功能 我还听说 C 标准委员会正在考虑将其添加到该语言中 恐怕我只是不明白它的意义 使用 RAII 和智能指针消除了它的需要 对吗 我唯一的垃圾收集经验是在几台廉价的八十年代家用计算机上 这意味着系统会时
  • 双重嵌套 for 循环的 Pythonic 快捷方式?

    考虑一下 如果我有一个接受元组参数 x y 的函数 其中 x 在范围 X 中 y 在范围 Y 中 则正常的做法是 for x in range X for y in range Y function x y 有什么办法吗 for xy in
  • AS3 中的堆栈限制 5287 是变量还是预定义的?

    我刚才做了一个测试 function overflow stack int 0 void if stack lt 5290 trace stack overflow stack 1 overflow 这总是会在之后抛出 StackOverf
  • SVG - 可以在一侧添加笔画破折号渐变或透明形式

    我创建了一个 SVG 动画 在其中允许中风虚线阵列移动 我是否可以在中风破折号数组的尾部添加渐变并保持一侧透明 如示例中所示 svg main width 700px margin 30px auto position relative s
  • 反应/Firebase。如何在项目中保存更新的数据?

    当我尝试更改数据时 更改正在进入我的 Firestore 数据库 没关系 但是当我重新加载页面或注销并尝试再次登录时 用户数据不会出现在我的项目中 但也会出现存储在我的Firestore Database 即使重新加载页面后 如何保存并显示