Google Cloud Services - Firebase Admin

This extension allows to inject both a com.google.firebase.FirebaseApp and a com.google.firebase.auth.FirebaseAuth object inside your Quarkus application.

Be sure to have read the Google Cloud Services extension pack global documentation before this one, it contains general configuration and information.

Bootstrapping the project

First, we need a new project. Create a new project with the following command (replace the version placeholder with the correct one):

mvn io.quarkus:quarkus-maven-plugin:${quarkusVersion}:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=firebase-admin-quickstart \
    -Dextensions="resteasy-reactive-jackson,quarkus-google-cloud-firebase-admin"
cd firebase-admin-quickstart

This command generates a Maven project, importing the Google Cloud Firebase Admin extension.

If you already have your Quarkus project configured, you can add the quarkus-google-cloud-firebase-admin extension to your project by running the following command in your project base directory:

./mvnw quarkus:add-extension -Dextensions="quarkus-google-cloud-firebase-admin"

This will add the following to your pom.xml:

<dependency>
    <groupId>io.quarkiverse.googlecloudservices</groupId>
    <artifactId>quarkus-google-cloud-firebase-admin</artifactId>
</dependency>

Some example

This is an example usage of the extension: we create a REST resource with a single endpoint that retrieves a user by UID.

import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseAuthException;
import com.google.firebase.auth.UserRecord;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/auth")
public class FirebaseAuthResourceTest {

    @Inject
    FirebaseAuth firebaseAuth;

    @GET
    @Path("/users/{uid}")
    @Produces(MediaType.APPLICATION_JSON)
    public UserRecord getUserById(@PathParam("uid") String uid) throws FirebaseAuthException {
        return firebaseAuth.getUser(uid);
    }

}

Firebase Authentication

This extension also supports Firebase Authentication, allowing you to secure your endpoints using Firebase’s authentication mechanisms. This section describes how to use Firebase Authentication in your Quarkus application.

Remember that you need to enable the Firebase Authentication service in your Firebase project. quarkus.google.cloud.firebase.auth.enabled must be set to true in your application configuration.

Configuration

  • quarkus.google.cloud.firebase.auth.enabled - Enable Firebase Authentication. Default value is false.

Example

If you want to access the user’s claims you can use SecurityIdentity:

import io.quarkus.security.identity.SecurityIdentity;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import org.eclipse.microprofile.jwt.JsonWebToken;

@Path("/app")
public class FirebaseAppResource {

    @Inject
    FirebaseApp firebaseApp;

    @Inject
    SecurityIdentity identity;

    @GET
    @Path("/options")
    @Produces(MediaType.APPLICATION_JSON)
    public FirebaseOptions getOptions() {
        if(identity.getPrincipal() instanceof JsonWebToken) {
            System.out.println("JWT: " + ((JsonWebToken) identity.getPrincipal()).getClaim("email"));
        }

        return firebaseApp.getOptions();
    }

}

As per the firebase cookie documentation you can also authenticate to Firebase using cookies. In this flow, there is no need to send additional headers after setting up the cookie in the browser, as the browser will automatically send the appropriate cookies. When using this approach the flow is as follows:

  1. The browser performs a regular login (using the firebase Oauth flow) to retrieve a JWT token

  2. The browser performs a login using the configured login endpoint. This endpoint responds with a Cookie (HTTP Only, Secure, SameSite) which the browser stores

  3. For every subsequent call, the browser sends along the cookie with the requests which the extension can use to authenticate the user. Note that if both headers and cookies are present, currently the headers take precedence.

  4. If a logout is needed, the browser can call the logout endpoint which effectively clears the cookie.

Note: this approach is e.g. conventient when you want to retrieve images in a secure way, as <img> tags don’t support a way to specify headers.

Configuration Reference

Configuration property fixed at build time - All other configuration properties are overridable at runtime

Configuration property

Type

Default

Enable or disable Firebase authentication.

Environment variable: QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_ENABLED

boolean

false

Enable session cookie support

Environment variable: QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_SESSION_COOKIE_ENABLED

boolean

false

Sets the emulator host to use.

Environment variable: QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_EMULATOR_HOST

string

Forces the usage of emulator credentials. The logic automatically uses emulator credentials in case the emulatorHost is set.

  • If true: force usage of emulator credentials

  • If false: force not using emulator credentials

Environment variable: QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_USE_EMULATOR_CREDENTIALS

boolean

true

When set, the values in this claim in the Firebase JWT will be mapped to the roles in the Quarkus io.quarkus.security.identity.SecurityIdentity. This claim can either be a set of roles (i.e. an array in the JWT) or a single value.

Environment variable: QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_ROLES_CLAIM

string

Name to use for session cookies (see Manage session cookies)

Environment variable: QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_SESSION_COOKIE_NAME

string

session

The expiration duration of the session cookie. Uses java.time.Duration#parse(CharSequence) to get a duration for the expiration. See the JavaDoc of this method for the format of this value.

Defaults to 5 days.

Environment variable: QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_SESSION_COOKIE_EXPIRATION_DURATION

Duration 

P5D

Perform an additional check to see if the session was revoked

Environment variable: QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_SESSION_COOKIE_CHECK_REVOKED

boolean

true

Validate the expiration date of the token.

Environment variable: QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_SESSION_COOKIE_VALIDATE_TOKEN

boolean

false

Minimum token validity in case validate-token() is set to true. Uses java.time.Duration#parse(CharSequence) to get a duration for the expiration. See the JavaDoc of this method for the format of this value.

Environment variable: QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_SESSION_COOKIE_MINIMUM_TOKEN_VALIDITY

Duration 

Path of an HTTP endpoint which can be used to perform the session login. If set, a reactive route will be registered to handle setting the cookie based on an authenticated request.

Environment variable: QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_SESSION_COOKIE_LOGIN_API_PATH

string

Path of an HTTP endpoint which can be used to perform the session logout. If set, a reactive route will be registered to handle clearing the session cookie.

Environment variable: QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_SESSION_COOKIE_LOGOUT_API_PATH

string

About the Duration format

To write duration values, use the standard java.time.Duration format. See the Duration#parse() Java API documentation for more information.

You can also use a simplified format, starting with a number:

  • If the value is only a number, it represents time in seconds.

  • If the value is a number followed by ms, it represents time in milliseconds.

In other cases, the simplified format is translated to the java.time.Duration format for parsing:

  • If the value is a number followed by h, m, or s, it is prefixed with PT.

  • If the value is a number followed by d, it is prefixed with P.