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
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
Make sure your Firestore database rules allow write operations for authenticated users.
This would typically allow read and write operations on a user document if the user is authenticated and the
userId
matches theuid
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.
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