Home > other >  How to make a data collection instead of replace old data on firebase?
How to make a data collection instead of replace old data on firebase?

Time:08-14

I am a beginner and I am making a crud project to pratice and develop my skill. The app is a Book list app. Now I am trying to add the book to firebase when user add a book. But when I am doing that It is replacing the old data.

Here is an image of firebase database:

enter image description here

In my app users can create an account. Then they will able to make book list. So I want to add users book list under their id. But how to do that.

Here is my code. Creating new data to firebase function is in the submitHandler function at line no 36.

AddBook.jsx

import React, { useState } from 'react';
import { useDispatch } from 'react-redux';
import { useNavigate } from 'react-router-dom';
import { addBook } from '../app/BooksSlice';
import { v4 as uuidv4 } from 'uuid';
import { auth, db } from '../firebase/firebase';
import { getAuth, createUserWithEmailAndPassword } from 'firebase/auth';
import {
  addDoc,
  collection,
  doc,
  serverTimestamp,
  setDoc,
} from 'firebase/firestore';

const AddBook = () => {
  const [data, setData] = useState({});

  const inputHandler = event => {
    event.preventDefault();
    const name = event.target.name;
    const value = event.target.value;
    setData({ ...data, [name]: value });
  };

  const dispatch = useDispatch();
  const navigate = useNavigate();

  const submitHandler = async event => {
    event.preventDefault();
    const books = { id: uuidv4(), title: data.title, author: data.author };
    dispatch(addBook(books));

    // creating data to firebase
    try {
      await setDoc(doc(db, 'books', auth.currentUser.uid), {
        title: data.title,
        author: data.author,
        id: uuidv4(),
        time: serverTimestamp(),
      });
    } catch (error) {
      console.log('Got and error while adding new data to firebase', error);
    }

    // Navigating to homepage after successfull login
    navigate('/show-books', { replace: true });
  };

  return (
    <div className="container bg-dark py-3 px-5 mt-3 rounded">
      <form onSubmit={submitHandler}>
        <div className="form-floating my-3">
          <input
            name="title"
            type="text"
            className="form-control"
            placeholder="Title"
            value={data.title}
            onChange={event => inputHandler(event)}
            required
          />
          <label>Title</label>
        </div>
        <div className="form-floating my-3">
          <input
            name="author"
            type="text"
            className="form-control"
            placeholder="Author"
            value={data.author}
            onChange={event => inputHandler(event)}
            required
          />
          <label>Author</label>
        </div>
        <button className="btn btn-lg btn-light" type="submit">
          Add Book
        </button>
      </form>
    </div>
  );
};

export default AddBook;

Can you help me to do that?

CodePudding user response:

You are currently saving the book with the ID of the user as document ID. This means, that the user can only have one book since the document IDs in a collection are unique.

This is shown in your code here:

// you are using the auth.currentUser.uid as document ID
await setDoc(doc(db, 'books', auth.currentUser.uid), ...);

If you want a user to be able to own multiple books, then you could add documents with randomly generated IDs and the userId as field on the document. This will still allow you to query data only for that user and will also still allow you to write security rules so that other users can not read and/or write the books. Check out this code snippet in the Firebase docs page, which uses the addDoc function. In your example, it could look like this

// we add the userId to the document body, so that a user can have multiple books
await addDoc(collection(db, 'books'), {
     userId: auth.currentUser.uid
     title: data.title,
     author: data.author,
     time: serverTimestamp(),
});

Please note, that the id field is also removed, since an ID will automatically be generated by Firestore.

  • Related