I am going to send a notification to ios devices by rails backend.
I have added grocer gem to Gemfile and then installed it in the project.
gem 'grocer'
I planed to send a notification in background mode. So I created resque job and added the grocer logic in app/jobs/notificationsender.rb like this.
def self.perform(language)
#lang = language
# Thread.new do
while true
begin
pusher = Grocer.pusher(certificate: "#{Rails.root}/lib/notification/cer.pem", # required
passphrase: "llvc", # optional
gateway: "gateway.sandbox.push.apple.com", # optional
port: 2195, #optional
retries: 3)
feedback = Grocer.feedback( certificate: "#{Rails.root}/lib/notification/cer.pem", # required
passphrase: "llvc",
gateway: "feedback.sandbox.push.apple.com",
port: 2196,
retries: 3)
note = Grocer::Notification.new(
device_token: device_token,
alert: message,
sound: 'default',
badge: 0,
expiry: Time.now + 60*60,
content_available: true,
custom: {
"linkname": linkname,
"linkurl": linkurl
}
)
feedback.each do |attempt|
puts "Device #{attempt.device_token} failed at #{attempt.timestamp}"
end
pusher.push(note)
rescue Exception => e
puts e.class
puts e
end
sleep(5)
end #while
end
I got a device token from iphone and sent it to backend.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
_deviceToken = deviceToken;
// Store the deviceToken in the current installation and save it to Parse.
if (currentInstallation == nil) {
currentInstallation = [[BSGInstallation alloc] init];
}
currentInstallation.delegate = self;
[currentInstallation setDeviceTokenFromData:deviceToken];
[currentInstallation saveInBackground];
}
I downloaded an apple pushnotification development certificate and generated p12 from it and then created cer.pem file from command line.
I signed the ios project with app development cer for debug and distribution for release and assigned development provisioning. Of course I added device identifier to the provisioning correctly.
After building ios, backend, resque job I got a notification after every 5 seconds in iPhone. I installed the app on iPad. but the notification doesn't get on the iPad. Of course the id of iphone and ipad were correctly registered. And I confirmed the device token of iphone and ipad was passed on the Grocer::notification.new()
but the notification doesn't work in iPad. So I reset the server and reinstalled on each devices. At first I tested for iPad. the result was the same. And then I move onto iPhone. the system also didn't work in the iphone. Before it worked. It was very strange.
So I want to know the followings.
1) the reason why the notification is received by iphone or ipad. I want to know the as many branches as possible so that i can detect the reason quickly by following the steps.
2) Can I check the notification is arrived until APNS?
Thanks for reading my long description.
There were no errors in IOS and rails code.
I have took a code signing in ios and created a pem file by the url.
https://www.raywenderlich.com/32960/apple-push-notification-services-in-ios-6-tutorial-part-1
I got an error when following the github tutorial.
Thanks.
Related
I've set up react-native-onesignal on my project to implement Push Notification using OneSignal.
It is possible to test Push Notification on iOS simulators since Xcode 11.4 Beta. I created JSON formatted apns file to test Push Notification on Simulator and it worked very well.
But how can I emulate OneSignal Push Notification?
I followed OneSignal Documentation and want to receive Push Notification which is sent from OneSignal Dashboard.
Here's what I've implemented on my App.tsx file.
const initializeOneSignal = () => {
OneSignal.setLogLevel(6, 0);
OneSignal.init("MY_ONESIGNAL_APP_ID", {
kOSSettingsKeyAutoPrompt: false,
kOSSettingsKeyInAppLaunchURL: false,
kOSSettingsKeyInFocusDisplayOption: 2,
});
OneSignal.inFocusDisplaying(2);
OneSignal.promptForPushNotificationsWithUserResponse(myiOSPromptCallback);
OneSignal.addEventListener('received', onPNReceived);
OneSignal.addEventListener('opened', onPNOpened);
OneSignal.addEventListener('ids', onPNIds);
};
useEffect(() => {
initializeOneSignal();
return () => {
OneSignal.removeEventListener('received', onPNReceived);
OneSignal.removeEventListener('opened', onPNOpened);
OneSignal.removeEventListener('ids', onPNIds);
};
}, []);
const onPNReceived = notification => {
console.log('Notification received: ', notification);
};
const onPNOpened = openResult => {
console.log('Message: ', openResult.notification.payload.body);
console.log('Data: ', openResult.notification.payload.additionalData);
console.log('isActive: ', openResult.notification.isAppInFocus);
console.log('openResult: ', openResult);
};
const onPNIds = device => {
console.log('Device info: ', device);
};
const myiOSPromptCallback = permissions => {
console.log('Permissions: ', permissions);
};
I cannot see any logged message when I sent Push Notification from my OneSignal Dashboard.
Do I need to do any trick in apns file?
Any help would be appreciated.
tl;dr you can't send a real notification to a simulator. You can only send mocked notifications to a simulator
Your server is oblivious of a simulator, because simulators don't have device tokens. Apple decided not to give it one. I suppose this was so users can't fake their device token and get notifications on their simulator...
The 11.4 simply allows the drag and drop of a APNs payload into the simulator without any mention of device token.
You can check out this article on Medium enter link description here.
This article helped me test oneSignal push notifications on my iOS simulator and figure out the deep linking issue.
Here are my steps:
Create a payload.apns file on your desktop
Put the following code inside it:
{
"Simulator Target Bundle": "com.example.app",
"aps": {
"alert": {
"title": "Push Notification",
"subtitle": "Test Push Notifications",
"body": "Testing Push Notifications on iOS Simulator",
}
},
"custom": {
"i": "notificationId as UUID",
"a": {"deeplinkKey": "{\"deeplinkDetailKey\":\"deeplinkDetailValue\"}", "launchURL": "example://collection/myCollectionId/type/1"}
}
}
Remember to replace com.example.app with your app bundle ID.
Run your app on the simulator, then close the app and keep metro open
Drag and drop payload.apns file on the simulator, you will see the notification to click on it. If you have done the 3rd step right, you should be redirected to your app
(Optional) If you need to test a deep link with the push notification, I haven't yet found the key oneSignal uses, but as you see in the .apns file above, I added a launchURL to the a which represents additionalData and handled catching and opening it manually in the app to test what's wrong with the deep link.
(Optional) To open a deep link in your app, you can use Linking API from react-native:
import {Linking} from 'react-native'
Linking.openURL("Path/to/launchURL")
I'm trying to set-up push notifications for my app.
I'm so far that, when the app is installed through Xcode (in development mode basically), I can successfully receive push notifications. However, as soon as I install the app from TestFlight and try to use the new device token, the APN answers with BadDeviceToken.
I did do my own research, but all the questions on this seem to be outdated: While these used *.pem and *.p12 certificates, I'm using a *.p8 certificate. As far as I understood, p8 certificates are for both development and production, so I don't see the problem here?
I'm using the edamov\pushok library from Github with this code:
<?php
require '../../vendor/autoload.php';
use Pushok\AuthProvider;
use Pushok\Client;
use Pushok\Notification;
use Pushok\Payload;
use Pushok\Payload\Alert;
$options = [
'key_id' => 'xxx', // The Key ID obtained from Apple developer account
'team_id' => 'xxx', // The Team ID obtained from Apple developer account
'app_bundle_id' => 'xxx', // The bundle ID for app obtained from Apple developer account
'private_key_path' => 'xxx (p8 certificate path)', // Path to private key
'private_key_secret' => null // Private key secret
];
$authProvider = AuthProvider\Token::create($options);
$alert = Alert::create()->setTitle('Hello!');
$alert = $alert->setBody('First push notification');
$payload = Payload::create()->setAlert($alert);
//set notification sound to default
$payload->setSound('default');
//add custom value to your notification, needs to be customized
$payload->setCustomValue('key', 'value');
$deviceTokens = ['xxx (device token from TestFlight installation)'];
$notifications = [];
foreach ($deviceTokens as $deviceToken) {
$notifications[] = new Notification($payload,$deviceToken);
}
$client = new Client($authProvider, $production = false);
$client->addNotifications($notifications);
$responses = $client->push(); // returns an array of ApnsResponseInterface (one Response per Notification)
foreach ($responses as $response) {
echo($response->getApnsId());
echo($response->getStatusCode());
echo($response->getReasonPhrase());
echo($response->getErrorReason());
echo($response->getErrorDescription());
}
So how can I setup the APN with a p8 certificate for production mode? Do I need to create a production certificate and somehow include it somewhere?
While trying to send push if app installed through Testflight did you keep the Sandbox enable or not?
I'm integrating push notification for iOS using the gem houston on Ruby on Rails as the web service but whenever I try to send a push notification, it only returns the number "94". Tested it a few hours ago, it returned the number "83" instead. What do you think is causing this and what does those numbers mean?
Code:
token = params[:user]["device_token"]
certificate = File.read("../flux-ws/public/certificates/#{PEM_FILE}")
passphrase = ""
connection = Houston::Connection.new(GATEWAY_URI, certificate, passphrase)
connection.open
notification = Houston::Notification.new(device: token)
notification.alert = {
:body => "HELLO WORLD"
}
notification.badge = 57
pushed_data = connection.write(notification.message)
connection.close
Return value:
{"pushed_data":94,"status":200}
Nevermind, guys. I solved it. The bundle id on the pem file didn't match with the bundle id on my project. That was what caused it and after I matched both, it delivered the push notification successfully.
I can't seem to figure out why my apple push notifications aren't working. My sandbox and production certificates are good until mid 2016. They were working at one point. When my app went live though, I noticed that they were not working.
On the server side, where I trigger the push notifications upon a user answering another users question, I am doing everything correctly still. Retrieving the device token from my DB, etc.
def send_notification(question_user, answer_user, alert, sound, data)
if question_user && answer_user
rememeber_tokens_for_user = RememberToken.where("user_id = ?", question_user.id)
if rememeber_tokens_for_user.size > 0
rememeber_tokens_for_user.each do |remember_token|
n = Rpush::Apns::Notification.new
n.app = Rpush::Apns::App.find_by_name("Roto Forum")
n.device_token = remember_token.device_token
n.alert = alert
n.badge = unread_answers_count_for_user_id(question_user.id)
n.sound = sound
n.data = data
n.save
end
Rpush.embed
end
end
end
However, no users end up with push notifications. I'm not sure where to start debugging this. It's on heroku. Does rpush supply some sort of logs, and if so, how would I obtain these from heroku? Does rpush have a table full of notifications in pending or sent/failed state? What's the best way to debug this?
I'm trying to use Houston to send a push notification. I recreated the provisioning profile, can upload a device token successfully, but when I push using apn the console shows no readout. Is there a way to log what APN is doing? (Submitted a github issue; posting here hoping someone's ran into this.
Running this code returns nothing. I've tried removing spaces & <> from the device token too, same result.
Using rspec 3.1.0
Using simplecov-html 0.8.0
require 'houston'
# Environment variables are automatically read, or can be overridden by any specified options. You can also
# conveniently use `Houston::Client.development` or `Houston::Client.production`.
APN = Houston::Client.production #tried development, same result
APN.certificate = File.read("/Users/quantum/Documents/cliqupprodcerts.pem")
# An example of the token sent back when a device registers for notifications
token = "tokentoken"
# Create a notification that alerts a message to the user, plays a sound, and sets the badge on the app
notification = Houston::Notification.new(device: token)
notification.alert = "Hello, World!"
# Notifications can also change the badge count, have a custom sound, have a category identifier, indicate available Newsstand content, or pass along arbitrary data.
notification.badge = 57
notification.sound = "sosumi.aiff"
notification.category = "INVITE_CATEGORY"
notification.content_available = true
notification.custom_data = {foo: "bar"}
# And... sent! That's all it takes.
v = APN.push(notification)
puts v
~
EDIT: I had tried production before, production & development don't work. puts notification.errors after sendings shows nothing.
First you should check whether you have had a develop profile that has a permission to push remote notification.
Then if your device is iOS 8.0 or later ,"Please use registerForRemoteNotifications and registerUserNotificationSettings: instead");
The last, you can do follow the steps of "houston"