Integrating Firebase Authentication with Devise Fallback in PropertyWebBuilder
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 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 acts as the single source of truth for determining which authentication system is active.
# 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:
# 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:
# 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 handles these routes with two critical before_action filters:
# 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:
# 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 is included in all Devise controllers (e.g., app/controllers/pwb/devise/sessions_controller.rb):
# 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:
# 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 provides unified path helpers that abstract the provider selection:
# 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:
<%# 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:
-
Update the environment variable:
export AUTH_PROVIDER=devise # or export AUTH_PROVIDER=firebase -
Restart the Rails server to reload the initializer.
-
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_PROVIDERtofirebaseordeviseinconfig/initializers/pwb_auth.rbto switch authentication systems without code changes. - Firebase Implementation: Uses
Pwb::FirebaseLoginControllerfor UI andPwb::FirebaseAuthServicewithPwb::FirebaseTokenVerifierfor token validation. - Devise Fallback: Standard Devise controllers include
AuthProviderRedirectto ensure Firebase routes redirect appropriately when Devise is active. - Unified Interface:
AuthHelpermethods likelogin_pathabstract 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →