Data Mutation

This page information on how you can mutate data on the Realtime Database, such as updating, deleting and or running transactions.

All hooks are built upon the useMutation hook, making it super simple to handle loading states, success and errors.

Setting data

To set data in the database, use the useDatabaseSetMutation hook.

import { useDatabaseSetMutation } from "@react-query-firebase/database";
import { ref } from "firebase/database";
import { database } from "./firebase";

function UpdateUser({ id }) {
  const dbRef = ref(database, `users/${id}`);
  const mutation = useDatabaseSetMutation(dbRef);

  return (
    <>
      <button
        disabled={mutation.isLoading}
        onClick={() => {
          mutation.mutate({
            name: "John Doe",
          });
        }}
      >
        Update User
      </button>
      {mutation.isError && <p>{mutation.error.message}</p>}
    </>
  );
}

To set data with priority, provide the priority option to the hook:

const mutation = useDatabaseSetMutation(dbRef, {
  priority: "high",
});

This will set data on the entire node, overriding anything which existed before. If you want to only set a sub-value on a node, provide a tighter reference instead:

const dbRef = ref(database, `user/123/name`);
const mutation = useDatabaseSetMutation(dbRef);

mutation.mutate("John Doe");

Updating nodes

To update data in the database, use the useDatabaseUpdateMutation hook.

Instead of taking the raw values of the node, you instead provide the child path to a node as the object key with the value to update.

import { useDatabaseUpdateMutation } from "@react-query-firebase/database";
import { ref } from "firebase/database";
import { database } from "./firebase";

function UpdateUser({ id }) {
  const dbRef = ref(database, `users/${id}`);
  const mutation = useDatabaseUpdateMutation(dbRef);

  return (
    <>
      <button
        disabled={mutation.isLoading}
        onClick={() => {
          mutation.mutate({
            name: "John Doe",
            "address/line1": "Mountain View",
          });
        }}
      >
        Update User
      </button>
      {mutation.isError && <p>{mutation.error.message}</p>}
    </>
  );
}

In this example, the mutation will update the users/:id/name and users/:id/address/line1 nodes at the same time.

Removing nodes

To remove data in the database, use the useDatabaseRemoveMutation hook.

import { useDatabaseUpdateMutation } from "@react-query-firebase/database";
import { ref } from "firebase/database";
import { database } from "./firebase";

function UpdateUser({ id }) {
  const dbRef = ref(database, `users/${id}/address`);
  const mutation = useDatabaseRemoveMutation(dbRef);

  return (
    <>
      <button
        disabled={mutation.isLoading}
        onClick={() => {
          mutation.mutate();
        }}
      >
        Remove User Address
      </button>
      {mutation.isError && <p>{mutation.error.message}</p>}
    </>
  );
}

In this example, the users/:id/address node will be removed. Any subscribers of this data will return null as the value once complete.

Running transactions

To perform a database transaction, use the useDatabaseTransaction hook. You can learn more by viewing the Firebase Transaction documentation.

import { useDatabaseTransaction } from "@react-query-firebase/database";
import { ref } from "firebase/database";
import { database } from "./firebase";

function LikePost({ id }) {
  const dbRef = ref(db, "post/123");
  const mutation = useDatabaseTransaction(dbRef, (post) => {
    if (post) {
      post.likes++;
    }

    return post;
  });

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

If you wish to get the result of the transaction (a TransactionResult), either await the mutation or wait for it to be successful:

const dbRef = ref(db, "post/123");

const mutation = useDatabaseTransaction(dbRef, (post) => {
  if (post) {
    post.likes++;
  }

  return post;
});

// Option 1: Await the mutation
const transactionResult = await mutation.mutateAsync();

// Option 2: Wait for success
if (mutation.isSuccess) {
  const transactionResult = mutation.data;
  console.log(transactionResult.committed);
  console.log(transactionResult.snapshot);
}