0

recently I'm struggling with adding APNs feature to my Ruby on Rails(7) project using RPush. I made some wrong config before and that lead to a failed launch of rails s, then I found and fixed it so I think all config is correct and service is running. Then I tried on heroku where my server is and I didn't get the APNs, then I tried it locally on my laptop, it shows me some error message which I cannot find a solution with Google or ChatGPT. Here is some error log below and I did work on it for a month as a beginner. Please let me know to correct it, thanks:

Started POST "/notifications/send_notifications" for ::1 at 2024-07-10 00:27:31 +0800
Processing by NotificationsController#send_notifications as TURBO_STREAM
  Parameters: {"authenticity_token"=>"[FILTERED]"}
  Rpush::Client::ActiveRecord::Apnsp8::App Load (0.5ms)  SELECT "rpush_apps".* FROM "rpush_apps" WHERE "rpush_apps"."type" = $1 AND "rpush_apps"."name" = $2 LIMIT $3  [["type", "Rpush::Client::ActiveRecord::Apnsp8::App"], ["name", "MyProjectName"], ["LIMIT", 1]]
  ↳ app/controllers/notifications_controller.rb:34:in `send_apns'
  TRANSACTION (0.4ms)  BEGIN
  ↳ app/controllers/notifications_controller.rb:38:in `send_apns'
  Rpush::Client::ActiveRecord::Apnsp8::Notification Create (2.2ms)  INSERT INTO "rpush_notifications" ("badge", "device_token", "sound", "alert", "data", "expiry", "delivered", "delivered_at", "failed", "failed_at", "error_code", "error_description", "deliver_after", "created_at", "updated_at", "alert_is_json", "type", "collapse_key", "delay_while_idle", "registration_ids", "app_id", "retries", "uri", "fail_after", "processing", "priority", "url_args", "category", "content_available", "notification", "mutable_content", "external_device_id", "thread_id", "dry_run", "sound_is_json") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31, $32, $33, $34, $35) RETURNING "id"  [["badge", nil], ["device_token", "[FILTERED]"], ["sound", nil], ["alert", "Your custom message"], ["data", "{\"foo\":\"bar\"}"], ["expiry", 86400], ["delivered", false], ["delivered_at", nil], ["failed", false], ["failed_at", nil], ["error_code", nil], ["error_description", nil], ["deliver_after", nil], ["created_at", "2024-07-09 16:27:31.439547"], ["updated_at", "2024-07-09 16:27:31.439547"], ["alert_is_json", false], ["type", "Rpush::Client::ActiveRecord::Apnsp8::Notification"], ["collapse_key", "[FILTERED]"], ["delay_while_idle", false], ["registration_ids", nil], ["app_id", 1], ["retries", 0], ["uri", nil], ["fail_after", nil], ["processing", false], ["priority", nil], ["url_args", nil], ["category", nil], ["content_available", false], ["notification", nil], ["mutable_content", false], ["external_device_id", nil], ["thread_id", nil], ["dry_run", false], ["sound_is_json", false]]
  ↳ app/controllers/notifications_controller.rb:38:in `send_apns'
  TRANSACTION (0.8ms)  COMMIT
  ↳ app/controllers/notifications_controller.rb:38:in `send_apns'
[2024-07-10 00:27:32][ERROR] [MyProjectName] Notification 11 failed, 403/InvalidProviderToken
Notification failed: 11
Redirected to http://localhost:3000/notifications
Completed 302 Found in 839ms (ActiveRecord: 21.2ms | Allocations: 78151)

Here is the config in rpush.rb

require 'jwt'

Rpush.configure do |config|
  config.client = :active_record
  config.push_poll = 2
  config.batch_size = 100
  config.pid_file = 'tmp/rpush.pid'
  config.log_file = 'log/rpush.log'

  config.log_level = (defined?(Rails) && Rails.logger) ? Rails.logger.level : ::Logger::Severity::INFO
end

Rpush.reflect do |on|

  on.notification_delivered do |notification|
    Rails.logger.info("Notification delivered: #{notification.id}")
  end

  on.notification_failed do |notification|
    Rails.logger.error("Notification failed: #{notification.id}")
  end
end

if Rpush::Apnsp8::App.where(name: 'RaceCal').empty?
  app = Rpush::Apnsp8::App.new
  app.name = 'RaceCal'
  apn_key_path = Rails.root.join('config', 'keys', 'AuthKey_xxx.p8')
  app.apn_key = File.read(apn_key_path)
  key_file = File.read(apn_key_path)
  app.environment = 'development' #'development' # or 'production'
  app.team_id = 'team id'
  app.apn_key_id = 'apn key'
  app.bundle_id = 'bundle_id'
  app.connections = 1
  app.save!

  token = JWT.encode({
    iss: team_id,
    iat: Time.now.to_i
  }, key_file, 'ES256', {
    kid: key_id
  })

  puts token
end

The code to trigger APNs in notifications_controller.rb

require 'jwt'

class NotificationsController < ApplicationController
  before_action :require_login, except: [:new, :create]

  def index
    # TODO
  end
  
  def send_notifications
    send_apns("my debug device token", "Your custom message")
    
    redirect_to notifications_path, notice: "Notifications sent successfully"
  end
  
  private
  
  def send_apns(device_token, message)
    n = Rpush::Apnsp8::Notification.new
    n.app = Rpush::Apnsp8::App.find_by_name("MyProjectName")
    n.device_token = device_token
    n.alert = message
    n.data = { foo: :bar }
    n.save!

    Rpush.push
    Rpush.apns_feedback
    
  end

  def admin_only
    unless current_user.admin?
      redirect_to root_path, alert: "You are not authorized to perform this action."
    end
  end

  def require_login
    redirect_to login_url unless session[:user_id]
  end
end

Then I click the send_notifications button, it shows the error log above.

1
  • I have no idea what the "rpush.rb" file is intended to do but team_id and key_id are not defined and token is unused. Otherwise the error is fairly clear that the provider token in invalid Commented Jul 9 at 17:44

0