skip to Main Content

I am using both Firebase auth and Firestore to store user information. I want to be able to store the users information under a document of the same id as the uid autogenerated when they create an account using the auth. My issue is that when I try to write the data to the firestore db it fails to complete.

here is the code for the initialization and where it is called.

// The firebase.js file
import firebase from "firebase/compat/app"
import "firebase/compat/auth"
import { getFirestore } from "firebase/firestore"

const app = firebase.initializeApp({
    apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
    authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
    projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
    storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
    messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID,
    appId: process.env.REACT_APP_FIREBASE_APP_ID,
    measurementId: process.env.REACT_APP_FIREBASE_MEASUREMENT_ID
})

export const auth = app.auth();
export default app;
export const db = getFirestore(app);


// Where the user will select a username to be tied to their account
import React, { useRef, useState} from "react";
import db from "../firebase"
import { doc, setDoc } from "firebase/firestore"
import {Form, Button, Card, Alert, Container} from 'react-bootstrap';
import { useAuth } from '../contexts/AuthContext';
import { useNavigate } from "react-router-dom";
import Header from "../components/Header"
import Footer from "../components/Footer"

export default function FinishSignup() {
    const { currentUser } = useAuth()
    const [error, setError] = useState('')
    const usernameRef = useRef()
    const navigate = useNavigate("/")
    const [loading, setLoading] = useState(false)

    async function handleSubmit(e) {
        e.preventDefault()
        const uid = currentUser.uid
        const email = currentUser.email

        try {
            setLoading(true)
            setError("")
            console.log(uid)
            console.log(email)
            console.log(usernameRef.current.value)
            await setDoc(doc(db, "users", uid), {
                username: usernameRef.current.value, 
                email: email
            })
            navigate("/")
        } catch {
            setError("Failed to complete signup")
        }

        setLoading(false)
    }

    return (
        <div style={{ backgroundColor: "#0b1321ff" }}>
            <Header />
            <Container className="d-flex align-items-center justify-content-center"
                style={{ minHeight: "100vh", backgroundColor: "#0b1321ff", color: '#b7c1d3ff' }}
            >
                <div className="w-100" style={{ maxWidth: '400px' }}>
                    <Card style={{ backgroundColor: "#0b1321ff", color: '#b7c1d3ff', border: '3px ridge #b7c1d3ff' }}>
                        <Card.Body>
                            <h2 className="text-center mb-4">Finish Setting Up Your Account</h2>
                            {error && <Alert variant="danger">{error}</Alert>}
                            <Form onSubmit={handleSubmit}>
                                <Form.Group id="username">
                                    <Form.Label>Username</Form.Label>
                                    <Form.Control type="text" ref={usernameRef} required />
                                </Form.Group>
                                <Button disabled={loading} className="w-100 text-center mt-2" type="submit"
                                    style={{backgroundColor: '#0b1321ff', color: '#67a170ff', border: '2px ridge #67a170ff'}}>Finish Signup</Button>
                            </Form>
                        </Card.Body>
                    </Card>
                </div>
            </Container>
            <Footer />
        </div>
    )
}

I’ve looked over all the related questions I could find but they all had different problems or their solutions didn’t work for my code. What is happening so far is that everything logs out to be what i’d expect and is a string, but the actual setDoc function fails and the catch statement kicks in before navigate function goes and when I check the database it is registering reads but not writes in addition to no new documents being created.

2

Answers


  1. So for you having trouble with Firestore not writing the data as expected. There are 2 suggestions which according to me would make things work

    1. Make sure your Firestore database rules allow write operations for authenticated users.

      rules_version = '2';
      service cloud.firestore {
      match /databases/{database}/documents {
           match /users/{userId} {
              allow read, write: if request.auth != null && request.auth.uid == userId;
              }
           }
      }
      

    This would typically allow read and write operations on a user document if the user is authenticated and the userId matches the uid of the authenticated user.

    2.Error Handling: It would be helpful to log the error in your catch block to understand what’s going wrong.

    catch (error) {
      console.error("Error writing document: ", error);
      setError("Failed to complete signup");
    }
    
    Login or Signup to reply.
  2. The issue is likely due to the inconsistent use firebase APIs, with version 9.8.1 you should be using the Modular API instead of compat.

    You can update your firebase initialization as follows to use the Modular API

    import { initializeApp } from "firebase/app";
    import { getAuth } from "firebase/auth";
    import { getFirestore } from "firebase/firestore";
    
    const firebaseConfig = {
        // your config
    };
    
    const app = initializeApp(firebaseConfig);
    export const auth = getAuth(app);
    export const db = getFirestore(app);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search