Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS push notification on Heroku Rails App — how to provide the PEM file

I am trying to send push notifications from my Rails app. I tried the gems APNS, Houston, and they work fantastic when I am on my development machine.

These gems need the /path/to/PEM/file (Apple’s certificate) to send the notifications. However, I can't seem to figure out how to provide this file on production server. I am using Heroku.

I tried having it uploaded to Amazon-S3 (non-public) and using it from there. However, this doesn’t work because the gems look for a local file (and not an URI). How do I save a local file on Heroku?

The gem APNS requires the path as a string. It then checks if the file exists.

raise "The path to your pem file does not exist!" unless File.exist?(self.pem)

The gem Houston requires the PEM as a File object. However, I cannot do File.open("url_to_my_pem_file")

like image 459
Rahul Jiresal Avatar asked Feb 18 '14 02:02

Rahul Jiresal


2 Answers

You could just use the Rails.root var to get a local path. Hosting your cert files on S3 might be a bit overkill, and you're making your push server dependent on S3 now. If there's downtime, you can't push. Also, you're going to be slowed down by making a web call.

Here's a sample method from my rails production push server:

def cert_path
    path = "#{Rails.root}/config/apn_credentials/"
    path += ENV['APN_CERT'] == 'production' ? "apn_gather_prod.pem" : "apn_gather_dev.pem"
    return path    
end
like image 113
Taylor Halliday Avatar answered Oct 18 '22 14:10

Taylor Halliday


I ended up copying the AWS-S3 file to the Heroku app, use the copied version (since it is local), and then delete the copied file once the notifications were sent.

fname = "tempfile.pem"
# open the file, and copy the contents from the file on AWS-S3
File.open(fname, 'wb') do |fo|
    fo.print open(AWS::S3::S3Object.url_for(LOCATION_ON_S3, BUCKET_NAME)).read
end
file = File.new(fname)
# use the newly created file as the PEM file for the APNS gem
APNS.pem = file 

device_token = '<a4e71ef8 f7809c1e 52a8c3ec 02a60dd0 b584f3d6 da51f0d1 c91002af 772818f2>'
APNS.send_notification(device_token, :alert => 'New Push Notification!', :badge => 1, :sound => 'default')

# delete the temporary file
File.delete(fname)

On second thoughts, I could've used private assets like in this question — Where to put private documents to use in Rails applications?, but even the answer mentions that AWS-S3 is probably a better idea.

like image 44
Rahul Jiresal Avatar answered Oct 18 '22 13:10

Rahul Jiresal