# Integrating Firebase Authentication with Devise Fallback in PropertyWebBuilder

> Seamlessly integrate Firebase Authentication with Devise fallback in PropertyWebBuilder. Switch auth via env variable without code changes. Streamline user logins effortlessly.

- Repository: [Ed Tee/property_web_builder](https://github.com/etewiah/property_web_builder)
- Tags: how-to-guide
- Published: 2026-03-01

---

**PropertyWebBuilder allows you to switch between Firebase Authentication and Devise with a single environment variable, automatically routing users to the correct login UI without changing any application code.**

This guide explains how to implement and toggle between Firebase and Devise authentication in the [PropertyWebBuilder](https://github.com/etewiah/property_web_builder) open-source Rails application. The architecture relies on a provider-agnostic configuration layer that delegates routing decisions at runtime based on the `AUTH_PROVIDER` environment variable.

## Selecting the Authentication Provider

The `Pwb::AuthConfig` module in [`config/initializers/pwb_auth.rb`](https://github.com/etewiah/property_web_builder/blob/main/config/initializers/pwb_auth.rb) acts as the single source of truth for determining which authentication system is active.

```ruby

# config/initializers/pwb_auth.rb

module Pwb
  module AuthConfig
    VALID_PROVIDERS = %i[firebase devise].freeze

    class << self
      def provider
        @provider ||= ENV.fetch('AUTH_PROVIDER', 'firebase').to_sym
      end

      def firebase?
        provider == :firebase
      end

      def devise?
        provider == :devise
      end
    end
  end
end

```

To switch providers, set the environment variable and restart the server:

```bash

# Use Firebase (default)

export AUTH_PROVIDER=firebase

# Use Devise fallback

export AUTH_PROVIDER=devise

```

The initializer validates the configuration at boot time and logs the active provider to the Rails log.

## Firebase Login Flow Implementation

When `AUTH_PROVIDER` is set to `firebase`, PropertyWebBuilder serves its own Tailwind-styled authentication UI through dedicated routes and controllers.

### Firebase Routes

The Firebase-specific endpoints are defined in [`config/routes.rb`](https://github.com/etewiah/property_web_builder/blob/main/config/routes.rb):

```ruby

# config/routes.rb

get "/pwb_login"            => "firebase_login#index"
get "/pwb_sign_up"          => "firebase_login#sign_up"
get "/pwb_forgot_password"  => "firebase_login#forgot_password"
get "/pwb_change_password"  => "firebase_login#change_password"

```

### Firebase Controller Logic

The `Pwb::FirebaseLoginController` in [`app/controllers/pwb/firebase_login_controller.rb`](https://github.com/etewiah/property_web_builder/blob/main/app/controllers/pwb/firebase_login_controller.rb) handles these routes with two critical `before_action` filters:

```ruby

# app/controllers/pwb/firebase_login_controller.rb

before_action :redirect_if_devise_auth
before_action :redirect_if_signed_in, except: [:change_password]

```

The `redirect_if_devise_auth` method ensures that if the provider is accidentally switched to Devise, users are redirected to the appropriate Devise path instead of seeing the Firebase UI.

### Token Verification and User Creation

When a user submits credentials via the Firebase UI, the client sends an ID token to the `/auth/firebase` endpoint. The `Pwb::FirebaseAuthService` validates this token using `Pwb::FirebaseTokenVerifier`:

```ruby

# app/services/pwb/firebase_auth_service.rb

verifier = FirebaseTokenVerifier.new(@token)
payload  = verifier.verify!

user = Pwb::User.find_by(firebase_uid: payload['sub'])

# Create or update user, assign roles, and sign in

```

The verifier handles certificate rotation, expiration checks, and issuer validation against Google's Firebase certificates.

## Devise Fallback and Automatic Redirection

When `AUTH_PROVIDER` is set to `devise`, PropertyWebBuilder delegates authentication to standard Devise controllers while ensuring Firebase routes remain inaccessible.

### AuthProviderRedirect Concern

The `AuthProviderRedirect` concern in [`app/controllers/concerns/auth_provider_redirect.rb`](https://github.com/etewiah/property_web_builder/blob/main/app/controllers/concerns/auth_provider_redirect.rb) is included in all Devise controllers (e.g., [`app/controllers/pwb/devise/sessions_controller.rb`](https://github.com/etewiah/property_web_builder/blob/main/app/controllers/pwb/devise/sessions_controller.rb)):

```ruby

# app/controllers/concerns/auth_provider_redirect.rb

def redirect_if_firebase_auth
  return if Pwb::AuthConfig.devise?
  
  firebase_path = firebase_equivalent_path
  redirect_to firebase_path, notice: "Please use the Firebase login."
end

```

### Path Mapping Logic

The concern maps Devise controller actions to their Firebase equivalents:

```ruby

# app/controllers/concerns/auth_provider_redirect.rb

base_path = case controller_name
            when 'sessions'      then '/pwb_login'
            when 'registrations' 
              action_name == 'edit' ? '/pwb_change_password' : '/pwb_sign_up'
            when 'passwords'     then '/pwb_forgot_password'
            else '/pwb_login'
            end

```

This ensures that if a user bookmarks `/users/sign_in` while Firebase is active, they are automatically redirected to `/pwb_login` without error.

## Helper Methods and View Integration

The `AuthHelper` module in [`app/helpers/auth_helper.rb`](https://github.com/etewiah/property_web_builder/blob/main/app/helpers/auth_helper.rb) provides unified path helpers that abstract the provider selection:

```ruby

# app/helpers/auth_helper.rb

def login_path(locale: nil)
  Pwb::AuthConfig.login_path(locale: locale)
end

def signup_path(locale: nil)
  Pwb::AuthConfig.signup_path(locale: locale)
end

```

Views use these helpers to generate links that automatically point to the correct authentication endpoint:

```erb
<%# app/views/layouts/_header.html.erb %>

<% if user_signed_in? %>
  <%= link_to "Logout", Pwb::AuthConfig.logout_path %>
<% else %>
  <%= link_to "Login", login_path %>
  <%= link_to "Sign up", signup_path %>
<% end %>

```

When `AUTH_PROVIDER` is `firebase`, these resolve to `/pwb_login` and `/pwb_sign_up`. When set to `devise`, they resolve to the localized Devise routes (e.g., `/en/users/sign_in`).

## Switching Between Providers at Runtime

To change authentication methods without deploying code:

1. **Update the environment variable:**
   ```bash
   export AUTH_PROVIDER=devise
   # or

   export AUTH_PROVIDER=firebase
   ```

2. **Restart the Rails server** to reload the initializer.

3. **Verify the switch** in the logs:
   ```

   [Pwb::AuthConfig] Using devise authentication
   ```

The application handles all routing and UI changes automatically. No database migrations or view modifications are required.

## Summary

- **Runtime Configuration:** Set `AUTH_PROVIDER` to `firebase` or `devise` in [`config/initializers/pwb_auth.rb`](https://github.com/etewiah/property_web_builder/blob/main/config/initializers/pwb_auth.rb) to switch authentication systems without code changes.
- **Firebase Implementation:** Uses `Pwb::FirebaseLoginController` for UI and `Pwb::FirebaseAuthService` with `Pwb::FirebaseTokenVerifier` for token validation.
- **Devise Fallback:** Standard Devise controllers include `AuthProviderRedirect` to ensure Firebase routes redirect appropriately when Devise is active.
- **Unified Interface:** `AuthHelper` methods like `login_path` abstract provider differences, allowing views to remain provider-agnostic.

## Frequently Asked Questions

### How do I switch from Firebase to Devise authentication?

Set the `AUTH_PROVIDER` environment variable to `devise` and restart your Rails server. The application will automatically redirect Firebase routes to their Devise equivalents and display standard Devise views instead of the Firebase UI.

### What happens if a user visits a Devise URL while Firebase is active?

The `AuthProviderRedirect` concern intercepts the request and redirects the user to the corresponding Firebase path. For example, visiting `/users/sign_in` redirects to `/pwb_login`, ensuring users always see the correct authentication interface for the active provider.

### How does PropertyWebBuilder verify Firebase ID tokens?

The `Pwb::FirebaseTokenVerifier` service validates tokens against Google's public certificates, checking issuer, audience, and expiration claims. The `Pwb::FirebaseAuthService` then uses the verified payload to find or create a user record based on the `firebase_uid` stored in the database.