Authentication Actions

When working with Authentication, it's common you'll want to perform authentication actions throughout your application, such as signing in a user, creating a user, triggering an OAuth flow, updating a user and lots more.

The React Query Firebase library supports all of the authentication actions by wrapping around the useMutation hook.

Although the Firebase SDK makes it super simple to perform these actions, it is still up to you to handle local state such as loading, errors and success. The hooks provided by this library make such scenarios simple.

For example, to sign a user in without the hooks, we need to handle many states ourselves:

import { signInWithEmailAndPassword } from "firebase/auth";
import { auth } from "./firebase";

function SignIn() {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [loading, setLoading] = useState("");
  const [error, setError] = useState("");

  async function onSignIn() {
    try {
      setLoading(true);
      await signInWithEmailAndPassword(auth, email, password);
    } catch (e) {
      setError(e.message);
    } finally {
      setLoading(false);
    }
  }

  return (
    <>
      <input value={email} onChange={(e) => setEmail(e.target.value)} />
      <input value={password} onChange={(e) => setPassword(e.target.value)} />
      <button disabled={loading} onClick={onSignIn}>
        Sign In
      </button>
      {!!error && <p>{error}</p>}
    </>
  );
}

Granted this could be cleaned up using form libraries and reducers, however repeating this process for the many authentication actions becomes tiresome.

Instead, with React Query Firebase we're able to quickly setup the same flow with minimal code:

import { useAuthSignInWithEmailAndPassword } from "@react-query-firebase/auth";
import { auth } from "./firebase";

function SignIn() {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const mutation = useAuthSignInWithEmailAndPassword(auth, {
    onError(error) {
      toast.error("Could not sign you in!");
    },
  });

  function onSignIn() {
    mutation.mutate({ email, password });
  }

  return (
    <>
      <input value={email} onChange={(e) => setEmail(e.target.value)} />
      <input value={password} onChange={(e) => setPassword(e.target.value)} />
      <button disabled={mutation.isLoading} onClick={onSignIn}>
        Sign In
      </button>
      {mutation.isError && <p>{mutation.error.message}</p>}
    </>
  );
}

By using the built in hooks, we abstract the async state handling to React Query, allowing us to focus building the UI and not local state management. Another bonus is we're able to provide the React Query mutation options to all of the hooks, allowing us to handle side-effects such as error handling!

Hooks#

Below is a list of all of the available hooks which wrap the Firebase API.

useAuthApplyActionCode#

Applies a verification code sent to the user by email or other out-of-band mechanism.

const mutation = useAuthApplyActionCode(auth);
mutation.mutate("oobCode");

useAuthCheckActionCode#

Checks a verification code sent to the user by email or other out-of-band mechanism.

const mutation = useAuthCheckActionCode(auth, {
  onSuccess(actionCodeInfo) {
    console.log("Valid action code!");
  },
  onError(error) {
    console.error("Invalid action code: ", error.code);
  },
});

mutation.mutate("oobCode");

useAuthConfirmPasswordReset#

Completes the password reset process, given a confirmation code and new password.

const mutation = useAuthCheckActionCode(auth);

mutation.mutate({
  oobCode: "...",
  newPassword: "...",
});

useAuthCreateUserWithEmailAndPassword#

Creates a new user account associated with the specified email address and password.

const mutation = useAuthCreateUserWithEmailAndPassword(auth);

mutation.mutate({
  email: "foo@bar.com",
  password: "...",
});

useAuthDeleteUser#

Deletes and signs out the user.

const mutation = useAuthDeleteUser(auth);

mutation.mutate();

useAuthLinkWithCredential#

Links the user account with the given credentials.

const mutation = useAuthLinkWithCredential();

mutation.mutate({
  user: auth.currentUser,
  // Any Auth credential supported...
  credential: EmailAuthProvider.credential('foo@bar.com', '...');
});

useAuthLinkWithPhoneNumber#

Links the user account with the given phone number.

const mutation = useAuthLinkWithPhoneNumber();

mutation.mutate({
  user: auth.currentUser,
  phoneNumber: '+44123456789'
  appVerifier: new RecaptchaVerifier('recaptcha'),
});

useAuthLinkWithPopup#

Links the authenticated provider to the user account using a pop-up based OAuth flow.

const mutation = useAuthLinkWithPopup();

mutation.mutate({
  user: auth.currentUser,
  // Any provider supported...
  provider: new GithubAuthProvider(),
});

useAuthLinkWithRedirect#

Links the OAuthProvider to the user account using a full-page redirect flow.

const mutation = useAuthLinkWithRedirect();

mutation.mutate({
  user: auth.currentUser,
  // Any provider supported...
  provider: new GithubAuthProvider(),
});

useAuthReauthenticateWithCredential#

Re-authenticates a user using a fresh credential.

const mutation = useAuthReauthenticateWithCredential();

mutation.mutate({
  user: auth.currentUser,
  // Any Auth credential supported...
  credential: EmailAuthProvider.credential('foo@bar.com', '...');
});

useAuthReauthenticateWithPhoneNumber#

Re-authenticates a user using a fresh phone credential.

const mutation = useAuthReauthenticateWithCredential();

mutation.mutate({
  user: auth.currentUser,
  phoneNumber: '+44123456789'
  appVerifier: new RecaptchaVerifier('recaptcha'),
});

useAuthReauthenticateWithPopup#

Reauthenticates the current user with the specified OAuthProvider using a pop-up based OAuth flow.

const mutation = useAuthReauthenticateWithPopup();

mutation.mutate({
  user: auth.currentUser,
  // Any provider supported...
  provider: new GithubAuthProvider(),
});

useAuthReauthenticateWithRedirect#

Reauthenticates the current user with the specified OAuthProvider using a full-page redirect flow.

const mutation = useAuthReauthenticateWithRedirect();

mutation.mutate({
  user: auth.currentUser,
  // Any provider supported...
  provider: new GithubAuthProvider(),
});

useAuthReload#

Reloads user account data, if signed in.

const mutation = useAuthReload();

mutation.mutate({
  user: auth.currentUser,
});

useAuthSendEmailVerification#

Sends a verification email to a user.

const mutation = useAuthSendEmailVerification();

mutation.mutate({
  user: auth.currentUser,
  actionCodeSettings: {...}, // optional
});

useAuthSendPasswordResetEmail#

Sends a password reset email to the given email address.

const mutation = useAuthSendPasswordResetEmail(auth);

mutation.mutate({
  email: 'foo@bar.com',
  actionCodeSettings: {...}, // optional
});

useAuthSendSignInLinkToEmail#

Sends a sign-in email link to the user with the specified email.

const mutation = useAuthSendPasswordResetEmail(auth);

mutation.mutate({
  email: 'foo@bar.com',
  actionCodeSettings: {...},
});

useAuthSignInAnonymously#

Asynchronously signs in as an anonymous user.

const mutation = useAuthSignInAnonymously(auth);

mutation.mutate();

useAuthSignInWithCredential#

Asynchronously signs in with the given credentials.

const mutation = useAuthSignInWithCredential(auth);

const credential = EmailAuthProvider.credential("foo@bar.com", "...");
mutation.mutate(credential);

useAuthSignInWithCustomToken#

Asynchronously signs in using a custom token.

const mutation = useAuthSignInWithCustomToken(auth);

mutation.mutate("xxxxx");

useAuthSignInWithEmailAndPassword#

Asynchronously signs in using a custom token.

const mutation = useAuthSignInWithEmailAndPassword(auth);

mutation.mutate({
  email: "foo@bar.com",
  password: "...",
});

useAuthSignInWithEmailLink#

Asynchronously signs in using an email and sign-in email link.

const mutation = useAuthSignInWithEmailLink(auth);

mutation.mutate({
  email: "foo@bar.com",
  emailLink: "https://...", // optional
});

useAuthSignInWithPhoneNumber#

Asynchronously signs in using a phone number.

const mutation = useAuthSignInWithPhoneNumber(auth);

mutation.mutate({
  phoneNumber: '+44123456789'
  appVerifier: new RecaptchaVerifier('recaptcha'),
});

useAuthSignInWithPopup#

Authenticates a Firebase client using a popup-based OAuth authentication flow.

const mutation = useAuthSignInWithPopup(auth);

mutation.mutate({
  // Any provider supported...
  provider: new GithubAuthProvider(),
});

useAuthSignInWithRedirect#

Authenticates a Firebase client using a full-page redirect flow.

const mutation = useAuthSignInWithRedirect(auth);

mutation.mutate({
  // Any provider supported...
  provider: new GithubAuthProvider(),
});

useAuthSignOut#

Signs out the current user.

const mutation = useAuthSignOut(auth);

mutation.mutate();

useAuthUnlink#

Unlinks a provider from a user account.

const mutation = useAuthUnlink();

mutation.mutate({
  user: auth.currentUser,
  providerId: "google.com",
});

useAuthUpdateCurrentUser#

Asynchronously sets the provided user as Auth.currentUser on the Auth instance.

const mutation = useAuthUpdateCurrentUser(auth);

mutation.mutate(user); // Some `User` instance
mutation.mutate(null); // Removes the user

useAuthUpdateEmail#

Updates the user's email address.

const mutation = useAuthUpdateEmail();

mutation.mutate({
  user: auth.currentUser,
  newEmail: "bar@foo.com",
});

useAuthUpdatePassword#

Updates the user's password.

const mutation = useAuthUpdatePassword();

mutation.mutate({
  user: auth.currentUser,
  newPassword: "...",
});

useAuthUpdatePhoneNumber#

Updates the user's phone number.

const mutation = useAuthUpdatePhoneNumber();

mutation.mutate({
  user: auth.currentUser,
  // PhoneAuthCredential returned from phone auth flow
  credential,
});

useAuthUpdateProfile#

Updates a user's profile data.

const mutation = useAuthUpdateProfile();

mutation.mutate({
  user: auth.currentUser,
  displayName: "...", // optional
  photoURL: "https://...", // optional
});

useAuthVerifyBeforeUpdateEmail#

Sends a verification email to a new email address.

const mutation = useAuthVerifyBeforeUpdateEmail();

mutation.mutate({
  user: auth.currentUser,
  newEmail: "bar@foo.com",
  actionCodeSettings: {}, // optional
});

useAuthVerifyPasswordResetCode#

Checks a password reset code sent to the user by email or other out-of-band mechanism.

const mutation = useAuthVerifyPasswordResetCode(auth);

mutation.mutate("oobCode");