You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React.js集成Firebase:实时数据库与存储数据添加失败求助

问题描述

用户已成功通过Firebase Authentication创建账户,但无法将用户数据写入Realtime Database,同时原本正常的Storage文件上传功能也失效。

相关代码

Register.jsx

import React, { useState } from 'react'
import profile from "../assets/user.png"
import { createUserWithEmailAndPassword, updateProfile } from "firebase/auth";
import { ref, set } from "firebase/database";
import { auth, storage, database } from '../firebase';
import { uploadBytesResumable, getDownloadURL } from "firebase/storage";

function Rejister() {
  const [err, setErr] = useState()

  const handleSubmit = async(e) => {
    e.preventDefault()
    const displayName = e.target[0].value
    const email = e.target[1].value
    const password = e.target[2].value
    const file = e.target[3].files[0]

    try {
      const res = await createUserWithEmailAndPassword(auth, email, password)
      console.log(res)
      const storageRef = ref(storage, `${displayName}/${file.name}`)
      const uploadTask = uploadBytesResumable(storageRef, file)

      uploadTask.on((err) => {
        setErr(true);
      }, ()=> {
        getDownloadURL(uploadTask.snapshot.ref)
          .then(async (downloadURL) => {
            await updateProfile(res.user, {
              displayName: displayName,
              photoURL: downloadURL,
            })
            await set(ref(database, 'users'), {
              username: displayName,
              email: email,
              photoURL : downloadURL
            });

            console.log('File available at', downloadURL);
          });
      })
    } catch (err) {
      setErr(true)
    }
  }

  return (
    <div className='formContainer'>
        <div className='formWrapper'>
            <span className='rejister-logo'>Talkies</span>
            <span className='rejister-title'>Rejister</span>
            <form className='rejistration-form' onSubmit={handleSubmit}>
                <input type="text" placeholder='Your Name' />
                <input type="email" placeholder='Email'/>
                <input type="password" placeholder='Password'/>
                <input type="file" id='file' style={{display: 'none'}} />
                <label htmlFor="file" className='file-uploder'>
                  <img src={profile} /> 
                  <span>Add Profile Photo</span>
                </label>
                <button className='sign-up-btn'>Sign Up</button>
                {err && <span> Something Went Wrong.</span>}
            </form>
            <p className='rejistration-para'>Do you already have an account? Login </p>
        </div>
    </div>
  )
}

export default Rejister;

Firebase_Config.js

import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
import { getFirestore } from "firebase/firestore";
import { getDatabase } from "firebase/database";
import { getStorage } from "firebase/storage";

const firebaseConfig = {
  apiKey: "**************************",
  authDomain: "**********************",
  projectId: "***********",
  storageBucket: "********************",
  messagingSenderId: "*****************",
  appId: "*************************************",
  measurementId: "**********"
};

export const app = initializeApp(firebaseConfig);
export const auth = getAuth(app)
export const storage = getStorage(app);
export const database = getDatabase(app);

问题排查与修复方案

1. 权限规则配置(最常见原因)

Firebase Realtime Database和Storage默认仅允许已认证用户读写,若规则配置错误会直接导致操作失败。

检查Realtime Database规则

进入Firebase控制台 → Realtime Database → 规则,确保规则允许已认证用户写入:

{
  "rules": {
    ".read": "auth != null",
    ".write": "auth != null"
  }
}

生产环境建议配置更严格的规则,比如仅允许用户修改自身数据

检查Storage规则

进入Firebase控制台 → Storage → 规则,确保规则允许已认证用户上传:

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

2. 代码逻辑修复

核心问题点

  • uploadTask.on参数错误:未指定事件类型,错误回调逻辑异常
  • 数据库写入逻辑错误:直接覆盖users节点所有数据,未按用户UID创建独立节点
  • 错误处理不完整:未捕获Storage上传、数据库写入的具体错误

修复后的核心代码

const handleSubmit = async(e) => {
  e.preventDefault()
  const displayName = e.target[0].value
  const email = e.target[1].value
  const password = e.target[2].value
  const file = e.target[3].files[0]

  // 校验文件是否存在
  if (!file) {
    setErr("请选择头像文件");
    return;
  }

  try {
    const res = await createUserWithEmailAndPassword(auth, email, password)
    console.log("用户创建成功:", res.user)

    // 用用户UID作为存储路径前缀,避免重名覆盖
    const storageRef = ref(storage, `user_avatars/${res.user.uid}/${file.name}`)
    const uploadTask = uploadBytesResumable(storageRef, file)

    // 正确配置上传状态监听
    uploadTask.on('state_changed', 
      (snapshot) => {
        // 可选:监听上传进度
        const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
        console.log('上传进度:', progress + '%');
      },
      (error) => {
        // 上传错误处理
        console.error("Storage上传失败:", error);
        setErr("头像上传失败,请重试");
      },
      async () => {
        try {
          const downloadURL = await getDownloadURL(uploadTask.snapshot.ref)
          console.log('文件地址:', downloadURL);

          // 更新用户Profile
          await updateProfile(res.user, {
            displayName: displayName,
            photoURL: downloadURL,
          })

          // 按用户UID写入数据库,避免覆盖其他用户数据
          await set(ref(database, `users/${res.user.uid}`), {
            username: displayName,
            email: email,
            photoURL: downloadURL,
            uid: res.user.uid
          });
          console.log("用户数据写入成功");

        } catch (dbError) {
          console.error("数据保存失败:", dbError);
          setErr("用户信息保存失败,请重试");
        }
      }
    )
  } catch (authError) {
    console.error("用户创建失败:", authError);
    setErr(authError.message || "注册失败,请重试");
  }
}

3. 其他可能原因

  • Firebase配置缺失:检查firebaseConfig是否包含databaseURL字段(Realtime Database必需),可从Firebase控制台项目设置中复制完整配置
  • 网络问题:确认客户端网络可正常访问Firebase服务
  • 认证状态异常:通过auth.currentUser验证用户是否在注册后处于已认证状态

内容的提问来源于stack exchange,提问作者codingWars

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 16:57:04