اذهب إلى المحتوى

السؤال

نشر

قمت بعمل صفحة تسجيل مستخدم جديد باستخدام firebase authentication مع الرياكت وهذه أكواد ملف firebase

import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
import { getStorage } from "firebase/storage";
import { getFirestore } from "firebase/firestore";
const firebaseConfig = {
  apiKey: "AIzaSyDF2qJJvU3SdodJ7ZfPDxmTwRvZUKuG8dA",
  authDomain: "chatapp-391c7.firebaseapp.com",
  projectId: "chatapp-391c7",
  storageBucket: "chatapp-391c7.appspot.com",
  messagingSenderId: "846028720986",
  appId: "1:846028720986:web:096532ddba9b7d76278163"
};

// Initialize Firebase
export const app = initializeApp(firebaseConfig);
export const auth = getAuth();
export const storage = getStorage();
export const db = getFirestore();

وهذه أكواد ملف Register.jsx

import React, { useState } from 'react';
import Add from "../img/addAvatar.png";
import { createUserWithEmailAndPassword, updateProfile } from "firebase/auth";
import { auth, db, storage } from "../firebase";
import { ref, uploadBytesResumable, getDownloadURL } from "firebase/storage";
import { doc, setDoc } from "firebase/firestore";

const Register = () => {
  const [err, setErr] = useState(false)

  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 = createUserWithEmailAndPassword(auth, email, password)

const storageRef = ref(storage, displayName);

const uploadTask = uploadBytesResumable(storageRef, file);

// Register three observers:
// 1. 'state_changed' observer, called any time the state changes
// 2. Error observer, called on failure
// 3. Completion observer, called on successful completion
uploadTask.on(
  (error) => {
    setErr(true)
  }, 
  () => {
    getDownloadURL(uploadTask.snapshot.ref).then( async(downloadURL) => {
      await updateProfile(res.user, {
        displayName,
        photoURL: downloadURL,
      });
      await setDoc(doc(db, "users", res.user.uid), {
        uid: res.user.uid,
        displayName,
        email,
        photoURL: downloadURL
      });
    });
  }
);
    }catch(err){

    }
  

  }

  return (
    <div className='formContainer'>
    <div className='formWrapper'>
      <span className='logo'>Chatgram</span>
      <span className='title'>تسجيل</span>
      <form onSubmit={handleSubmit}>
        <input type="text" placeholder='الاسم'/>
        <input type="email" placeholder='البريد الإلكتروني'/>
        <input type="password" placeholder='كلمة المرور'/>
        <input style={{display:'none'}} type="file" id="file"/>
        <label htmlFor="file">
          <img src={Add} alt="" />
          <span>أضف صورة</span>
        </label>
        <button>تسجيل</button>
        {err && <span>!! بياناتك ليست صحيحة</span>}
      </form>
      <p>لديك حساب بالفعل؟ تسجيل دخول</p>
    </div>
    </div>
  )
}

export default Register

ولكن عندما أحاول تسجيل مستخدم جديد يظهر لي هذا الخطأ

 

بدون عنوان.png

Recommended Posts

  • 0
نشر

المشكلة هي أنك تحاول تحميل صورة لمستخدم جديد باستخدام اسم المستخدم كاسم الملف في Firebase Storage وتحميل الصورة قبل أن يتم إنشاء المستخدم في Firebase Authentication.

أي أن السطر التالي في ملف Register.jsx هو السبب في حدوث الخطأ:

const storageRef = ref(storage, displayName);

وعند تشغيل ذلك السطر، يتم البحث عن مجلد أو ملف باسم المستخدم (displayName) في Firebase Storage، ولكن بما أن المستخدم لم يتم إنشاؤه بعد (إذ لم يتم إنجاز عملية createUserWithEmailAndPassword بنجاح)، فإن Firebase يقوم بإرجاع خطأ بسبب عدم وجود المستخدم.

لذلك حاول تأجيل عملية تحميل الصورة حتى يتم إنشاء المستخدم بنجاح، عن طريق تحويل جزء من الكود داخل المحاولة (try) إلى جزء من التأكيد (then) في Promise الذي يتم إرجاعه من createUserWithEmailAndPassword.

قم بتحديث الكود في ملف Register.jsx كما يلي:

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);

    // تم إنشاء المستخدم بنجاح، يمكن الآن متابعة عملية تحميل الصورة
    const storageRef = ref(storage, displayName);
    const uploadTask = uploadBytesResumable(storageRef, file);

    // باقي الكود لتحميل الصورة وتحديث بيانات المستخدم يبقى كما هو
    // ...
  } catch (err) {
    // يمكنك معالجة الخطأ هنا إذا لزم الأمر
  }
};

 

  • 1
نشر

الخطأ الذي تواجهه يرجع على الأرجح إلى محاولة استخدام دالة createUserWithEmailAndPassword بشكل غير صحيح. هذه الدالة هي دالة غير متزامنة وتعيد موعدًا بدلاً من كائن مستخدم (User object). يجب عليك انتظار إنشاء المستخدم ومن ثم استخدام الكائن المستخدم (User object) لإضافة المزيد من التفاصيل له والتحكم فيه.

لتصحيح هذا الخطأ، قم بتغيير كود التسجيل في ملف Register.jsx على النحو التالي:

  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 {
      // انتظر إنشاء المستخدم من خلال اضافة await
      const res = await createUserWithEmailAndPassword(auth, email, password); 

      const storageRef = ref(storage, displayName);
      const uploadTask = uploadBytesResumable(storageRef, file);

      uploadTask.on(
        "state_changed",
        (snapshot) => {},
        (error) => {
          setErr(true);
        },
        () => {
          getDownloadURL(uploadTask.snapshot.ref).then(async (downloadURL) => {
            await updateProfile(res.user, {
              displayName,
              photoURL: downloadURL,
            });
            await setDoc(doc(db, "users", res.user.uid), {
              uid: res.user.uid,
              displayName,
              email,
              photoURL: downloadURL,
            });
          });
        }
      );
    } catch (error) {
      setErr(true);
    }
  };

تأكد من إضافة الكلمة الأساسية await قبل استدعاء دالة createUserWithEmailAndPassword لانتظار إنشاء المستخدم والحصول على الكائن المستخدم (User object)، وذلك لتجنب الخطأ الذي واجهته في المحاولة السابقة.

  • 0
نشر
بتاريخ On 21‏/7‏/2023 at 11:39 قال Hessen Alosh:

الخطأ الذي تواجهه يرجع على الأرجح إلى محاولة استخدام دالة createUserWithEmailAndPassword بشكل غير صحيح. هذه الدالة هي دالة غير متزامنة وتعيد موعدًا بدلاً من كائن مستخدم (User object). يجب عليك انتظار إنشاء المستخدم ومن ثم استخدام الكائن المستخدم (User object) لإضافة المزيد من التفاصيل له والتحكم فيه.

لتصحيح هذا الخطأ، قم بتغيير كود التسجيل في ملف Register.jsx على النحو التالي:

  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 {
      // انتظر إنشاء المستخدم من خلال اضافة await
      const res = await createUserWithEmailAndPassword(auth, email, password); 

      const storageRef = ref(storage, displayName);
      const uploadTask = uploadBytesResumable(storageRef, file);

      uploadTask.on(
        "state_changed",
        (snapshot) => {},
        (error) => {
          setErr(true);
        },
        () => {
          getDownloadURL(uploadTask.snapshot.ref).then(async (downloadURL) => {
            await updateProfile(res.user, {
              displayName,
              photoURL: downloadURL,
            });
            await setDoc(doc(db, "users", res.user.uid), {
              uid: res.user.uid,
              displayName,
              email,
              photoURL: downloadURL,
            });
          });
        }
      );
    } catch (error) {
      setErr(true);
    }
  };

تأكد من إضافة الكلمة الأساسية await قبل استدعاء دالة createUserWithEmailAndPassword لانتظار إنشاء المستخدم والحصول على الكائن المستخدم (User object)، وذلك لتجنب الخطأ الذي واجهته في المحاولة السابقة.

شكرا لك

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...