Ruby on Rails集成Firebase实现iOS/Android推送通知Gem推荐及方案咨询
Hey there! Since you're wrapping up your Rails project and need to add Firebase push notifications for when a new service is registered, let me break down exactly how to do this step by step—perfect for someone new to notifications and mobile devices!
The most reliable option is the official firebase-admin gem, which lets you interact with Firebase Cloud Messaging (FCM) directly from your Rails backend. Add it to your Gemfile:
gem 'firebase-admin'
Then run bundle install to install it.
Head over to your Firebase Console:
- Go to Project Settings > Service Accounts
- Click Generate New Private Key and download the JSON file
- Save this file to your Rails project's
configdirectory (name it something likefirebase_service_account.json) - Critical: Add this file to your
.gitignoreright away—never commit sensitive credentials to version control!
Create a new initializer file at config/initializers/firebase.rb to set up the SDK when your Rails app starts:
require "firebase-admin" FirebaseAdmin::App.initialize_app( credential: FirebaseAdmin::Credentials.from_file(Rails.root.join("config/firebase_service_account.json")), project_id: "your-firebase-project-id" # Replace with your actual project ID from Firebase Console )
To send notifications to all employees, you need to save each employee's FCM device token (this token is generated by the mobile app when the user registers for push notifications).
First, add a device_token field to your Employee model with a migration:
rails generate migration AddDeviceTokenToEmployees device_token:string rails db:migrate
Make sure your mobile app sends this token to your Rails backend when an employee logs in or registers, and save it to the corresponding Employee record.
Now, add the logic to trigger the notification whenever a new service is registered. You can use an after_create callback on your Service model, or call it directly from your controller's create action.
Option 1: Model Callback
Add this to your app/models/service.rb:
class Service < ApplicationRecord after_create :send_new_service_notification private def send_new_service_notification # Get all employees who have a valid device token employee_tokens = Employee.where.not(device_token: nil).pluck(:device_token) # Exit early if there are no tokens to send to return if employee_tokens.empty? # Build the notification payload notification_message = { notification: { title: "New Service Alert", body: "a new service has been generated" }, tokens: employee_tokens # Send to all employee tokens at once } # Send the notification via FCM FirebaseAdmin::Messaging.send_all([notification_message]) end end
Option 2: Controller Action
If you prefer to handle it in your controller (e.g., ServicesController):
def create @service = Service.new(service_params) if @service.save send_new_service_notification # Add your success response logic here (e.g., redirect or JSON response) else # Handle validation errors end end private def send_new_service_notification employee_tokens = Employee.where.not(device_token: nil).pluck(:device_token) return if employee_tokens.empty? notification_message = { notification: { title: "New Service Alert", body: "a new service has been generated" }, tokens: employee_tokens } FirebaseAdmin::Messaging.send_all([notification_message]) end
- Handle Invalid Tokens: Over time, device tokens can expire or become invalid. The
send_allmethod returns a response object that lets you check for failures. You can use this to remove invalid tokens from your database:response = FirebaseAdmin::Messaging.send_all([notification_message]) response.responses.each_with_index do |result, index| if result.error token = employee_tokens[index] Employee.where(device_token: token).update(device_token: nil) end end - Test First: Use Firebase Console's Cloud Messaging > Send your first message tool to test sending notifications to a single token before rolling out to all employees.
- Background Jobs: If you expect high traffic, consider moving the notification logic to a background job (like Sidekiq) to avoid slowing down your request response time.
内容的提问来源于stack exchange,提问作者Jonathan Zambrano

