---
title: Data Mutation | Firestore
description: Hooks for integrating with Firestore.
---

# Data Mutation

This page information on how you can mutate data on Firestore, such as
updating and deleting, or running transactions and write batches.

All hooks are built upon the [`useMutation`](https://react-query.tanstack.com/reference/useMutation)
hook, making it super simple to handle loading states, success and errors.

## Adding a document to a collection

To add a document to a collection, use the `useFirestoreCollectionMutation` hook.
It accepts a `CollectionReference` and when the mutation is triggered, the provided
data is added as a new document.

```jsx
import { useFirestoreCollectionMutation } from "@react-query-firebase/firestore";
import { collection } from "firebase/firestore";
import { firestore } from "./firebase";

function AddDocument() {
  const ref = collection(firestore, "products");
  const mutation = useFirestoreCollectionMutation(ref);

  return (
    <>
      <button
        disabled={mutation.isLoading}
        onClick={() => {
          mutation.mutate({
            name: "New product!",
            price: 10,
          });
        }}
      >
        Add document
      </button>
      {mutation.isError && <p>{mutation.error.message}</p>}
    </>
  );
}
```

## Setting / Updating a document

If you need to set or update the data on an existing document, use
the `useFirestoreDocumentMutation` hook.

```jsx
import { collection, doc } from "firebase/firestore";
import { useFirestoreDocumentMutation } from "@react-query-firebase/firestore";
import { firestore } from "./firebase";

function SetDocument() {
  const collection = collection(firestore, "products");
  const ref = doc(collection, "123");
  const mutation = useFirestoreDocumentMutation(ref);

  return (
    <>
      <button
        disabled={mutation.isLoading}
        onClick={() => {
          mutation.mutate({
            name: "New product!",
            price: 20,
          });
        }}
      >
        Set document
      </button>
      {mutation.isError && <p>{mutation.error.message}</p>}
    </>
  );
}
```

In this example, the document will be overwritten with the provided data.
You can optionally pass [`SetOptions`](https://firebase.google.com/docs/reference/js/firestore_.md#setoptions)
to indiciate you wish to merge data instead:

```js
const mutation = useFirestoreDocumentMutation(ref, {
  merge: true,
});
```

## Deleting a document

To delete a document from your collection, use the `useFirestoreDocumentDeletion` hook.

```jsx
import { collection, doc } from "firebase/firestore";
import { useFirestoreDocumentDeletion } from "@react-query-firebase/firestore";
import { firestore } from "./firebase";

function DeleteDocument() {
  const collection = collection(firestore, "products");
  const ref = doc(collection, "456");
  const mutation = useFirestoreDocumentDeletion(ref);

  return (
    <>
      <button
        disabled={mutation.isLoading}
        onClick={() => {
          mutation.mutate();
        }}
      >
        Delete document
      </button>
      {mutation.isError && <p>{mutation.error.message}</p>}
    </>
  );
}
```

## Running Transactions

To run a transaction, use the `useFirestoreTransaction` hook. The hook
allows you to define the transaction function and execute it when ready.

```jsx
import { collection, doc } from "firebase/firestore";
import { useFirestoreTransaction } from "@react-query-firebase/firestore";
import { firestore } from "./firebase";

function LikeButton() {
  const collection = collection(firestore, "products");
  const ref = doc(collection, "123");
  const mutation = useFirestoreTransaction(ref, async (tsx) => {
    // Get the document
    const doc = await tsx.get(ref);

    const newLikes = doc.data().likes + 1;

    // Increase the `likes` count
    tsx.update(ref, {
      likes: newLikes,
    });

    return newLikes;
  });

  return (
    <>
      <button
        disabled={mutation.isLoading}
        onClick={() => {
          mutation.mutate();
        }}
      >
        Like!
      </button>
      {mutation.isError && <p>{mutation.error.message}</p>}
    </>
  );
}
```

To learn more about transactions, read the [Firestore guide](https://firebase.google.com/docs/firestore/manage-data/transactions#transactions).

## Write Batches

To execute many updates at once, use the `useFirestoreWriteBatch` hook.
Provide the hook with a `WriteBatch` instance, add batches writes and commit
the batch with the mutation trigger.

```jsx
import { writeBatch, collection, doc } from "firebase/firestore";
import { useFirestoreWriteBatch } from "@react-query-firebase/firestore";
import { firestore } from "./firebase";

function WriteBatchDocuments() {
  // Define the WriteBatch instance
  const batch = writeBatch(firestore);

  const ref = doc(collection(firestore, "products"), "123");

  const mutation = useFirestoreWriteBatch(batch);

  return (
    <>
      {/* Update the WriteBatch instance */}
      <button onClick={() => batch.delete(ref)}>Stage Deletion</button>
      {/* Commit the write batch */}
      <button
        disabled={mutation.isLoading}
        onClick={() => {
          mutation.mutate();
        }}
      >
        Like!
      </button>
      {mutation.isError && <p>{mutation.error.message}</p>}
    </>
  );
}
```

## Side Effects

All mutation hooks are built on-top of the [`useMutation`](https://react-query.tanstack.com/reference/useMutation) hook,
and allow you define mutation side effects:

```js
const mutation = useFirestoreCollectionMutation(ref, {
  onSuccess() {
    toast.success("Document added!");
  },
  onError(error) {
    toast.error("Failed to add document!");
  },
  onMutate() {
    toast.info("Adding document...");
  },
});

// or on the mutation function!
mutation.mutate(
  { name: "New Product!" },
  {
    onSuccess() {
      toast.success("Document added!");
    },
    onError(error) {
      toast.error("Failed to add document!");
    },
    onMutate() {
      toast.info("Adding document...");
    },
  }
);
```
