Can I use APNs Auth Key .p8 file with PHP to send iOS push notifications? - php

My push notifications stopped working with one of the recent updates. When I looked into it more, I discovered that Apple now lets you generate a non-expiring APNs Auth Key that works for both production and test. I have it working with the following node.js script:
var apn = require('apn');
// Set up apn with the APNs Auth Key
var apnProvider = new apn.Provider({
token: {
key: 'apns.p8', // Path to the key p8 file
keyId: '<my key id>', // The Key ID of the p8 file (available at https://developer.apple.com/account/ios/certificate/key)
teamId: '<my team id' // The Team ID of your Apple Developer Account (available at https://developer.apple.com/account/#/membership/)
},
production: false // Set to true if sending a notification to a production iOS app
});
// Enter the device token from the Xcode console
var deviceToken = '<my device token>';
// Prepare a new notification
var notification = new apn.Notification();
// Specify your iOS app's Bundle ID (accessible within the project editor)
notification.topic = '<my bundle id';
// Set expiration to 1 hour from now (in case device is offline)
notification.expiry = Math.floor(Date.now() / 1000) + 3600;
// Set app badge indicator
notification.badge = 3;
// Play ping.aiff sound when the notification is received
notification.sound = 'ping.aiff';
// Display the following message (the actual notification text, supports emoji)
notification.alert = 'This is a test notification \u270C';
// Send any extra payload data with the notification which will be accessible to your app in didReceiveRemoteNotification
notification.payload = {id: 123};
// Actually send the notification
apnProvider.send(notification, deviceToken).then(function(result) {
// Check the result for any failed devices
console.log(result);
process.exit(0)
});
Is there any way to use the new APNs Auth Key with PHP? I can call the node.js script from PHP, using exec("node app.js &", $output);, and it works, but it starts to get ugly. Should PHP still work using the old .pem file approach?

Related

Ngrok errors 502 bad gateway Twilio

Hi evreyone Im using twilio voice javascript sdk with ngrok that i found their repository in github
the installation went good when i try to click on start up the divice to get the client name from my name generator js an error has showed and i can not get the cleint client name or make any calls
i have set up my index js with all my account sid and phone number and twiml app sid and Twilio api secret key
cmd error
Error: identity is required to be specified in options
at new AccessToken (C:\xampp\htdocs\voice-javascript-sdk-quickstart-node\node_modules\twilio\lib\jwt\AccessToken.js:202:19)
at tokenGenerator (C:\xampp\htdocs\voice-javascript-sdk-quickstart-node\src\handler.js:13:23)
at C:\xampp\htdocs\voice-javascript-sdk-quickstart-node\src\router.js:7:12
at Layer.handle [as handle_request] (C:\xampp\htdocs\voice-javascript-sdk-quickstart-node\node_modules\express\lib\router\layer.js:95:5) at next (C:\xampp\htdocs\voice-javascript-sdk-quickstart-node\node_modules\express\lib\router\route.js:144:13)
at Route.dispatch (C:\xampp\htdocs\voice-javascript-sdk-quickstart-node\node_modules\express\lib\router\route.js:114:3)
at Layer.handle [as handle_request] (C:\xampp\htdocs\voice-javascript-sdk-quickstart-node\node_modules\express\lib\router\layer.js:95:5) at C:\xampp\htdocs\voice-javascript-sdk-quickstart-node\node_modules\express\lib\router\index.js:284:15
at Function.process_params (C:\xampp\htdocs\voice-javascript-sdk-quickstart-node\node_modules\express\lib\router\index.js:346:12)
at next (C:\xampp\htdocs\voice-javascript-sdk-quickstart-node\node_modules\express\lib\router\index.js:280:10)
ngrok error when i click on start up the device
HTTP Requests
-------------
GET /quickstart.js 200 OK
GET /twilio.min.js 200 OK
GET /site.css 200 OK
GET / 200 OK
GET / 502 Bad Gateway
config.js
const dotenv = require("dotenv");
const cfg = {};
if (process.env.NODE_ENV !== "test") {
dotenv.config({ path: ".env" });
} else {
dotenv.config({ path: ".env.example", silent: true });
}
// HTTP Port to run our web application
cfg.port = process.env.PORT || 3000;
// Your Twilio account SID and auth token, both found at:
// https://www.twilio.com/user/account
//
// A good practice is to store these string values as system environment
// variables, and load them from there as we are doing below. Alternately,
// you could hard code these values here as strings.
cfg.accountSid = process.env.TWILIO_ACCOUNT_SID;
cfg.twimlAppSid = process.env.TWILIO_TWIML_APP_SID;
cfg.callerId = process.env.TWILIO_CALLER_ID;
cfg.apiKey = process.env.TWILIO_API_KEY;
cfg.apiSecret = process.env.TWILIO_API_SECRET;
// Export configuration object
module.exports = cfg;

FCM push notification issue: "error":"NotRegistered"

I am getting weird issue of sending push notification to Android using FCM.
Goal :- Having error while sending push notification
Below is the scenario I do have function for sending push notification to Android
public static function SendMultipleNotificationAndroid($groups)
{
//your api key SERVER API KEY
$apiKey = Yii::$app->params['android_api_key'];
$url = 'https://fcm.googleapis.com/fcm/send';
$headers = array(
'Authorization:key=' . $apiKey,
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
foreach($groups as $resG){
$users = $resG['users'];
$msg = $resG['message'];
$type = $resG['notification_type'];
$notification_data = $resG['notification_data'];
$deviceTokens = [];
foreach($users as $resUser){
$deviceTokens[] = $resUser['device_token'];
//Add Friend badge count +1
Common::AddRemoveBadgeCount($resUser['user_id']);
}
if(!empty($deviceTokens)){
$fields = array(
'registration_ids' => $deviceTokens,
'priority' => 'high',
'collapse_key' => $resG['notification_type'],
'time_to_live' => 2419200,
"click_action" =>"NotificationListingActivity",
'data' => [
"title" => "ProjectName",
"body" => $resG['message'],
"action_tag" => $resG['notification_type'],
"message" => $resG['message'],
'notification_type' => $type,
'notification_data' => $notification_data,
'sound' => 'default',
]
);
//Print result
p($ch,0);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
curl_exec($ch);
}
}
curl_close($ch);
}
So the issue is when I send single notification it works fine but when I send multiple notification I got error every time
<pre>Resource id #5</pre>{"multicast_id":4818908994630396118,"success":1,"failure":1,"canonical_ids":0,"results":[{"error":"NotRegistered"},{"message_id":"0:1487136045570022%c3bae3c6002e9358"}]}
<pre>Resource id #5</pre>{"multicast_id":5218359780835228544,"success":1,"failure":1,"canonical_ids":0,"results":[{"error":"NotRegistered"},{"message_id":"0:1487136046618669%c3bae3c6002e9358"}]}
As we debug the code we do have device token in our database no firewall which stops sending push notifications.
Every time I call above function I get
"error":"NotRegistered"
According to the doc its because the mobile device testing does not have your app installed anymore
If it is NotRegistered, you should remove the registration ID from
your server database because the application was uninstalled from the
device, or the client app isn't configured to receive messages.
Don't know much about php, but recently I have faced the same issue in another project and I have resolved this way :
Refere this first :
Where can I find the API KEY for Firebase Cloud Messaging?
and get updated API key as shown in below snapshot
This is a client-side (device) issue, not service-side.
Multiple scenarios can cause this:
If the client app unregisters with GCM.
If the client app is automatically unregistered, which can happen if the user uninstalls the application. For example, on iOS, if the APNS Feedback Service
reported the APNS token as invalid.
If the registration token expires (for example, Google might decide to refresh registration tokens, or the APNS token has expired for iOS devices).
If the client app is updated but the new version is not configured to receive messages.
See https://developers.google.com/cloud-messaging/http-server-ref
On app startup I check to see if the token I have stored locally matches the new token. If not then I refresh the token on my servers. I also do this in FirebaseInstanceIDService::onTokenRefresh.
The thing is firebase generates a unique device-ID for your target device when the app is run for the first time, and it will be used as the identity of the device.
If the user uninstalls the app or clears the data of the app then in that case on reinstalling or reopening the app the device-ID will differ. This will result in the ID not be identified by firebase to send the notification. This will result in the error Not Registered
I got this error when i uninstalled and reinstalled my application.
What i think is, when we reinstall application, we cant get a new fcm token every time we install.
So, we must first delete the previous instance id and then create new fcm token. Please see the code below..
Just adding the uncommented line resolved my issue..
See first comment for this solution for code :)
_firebaseRegister() {
// _firebaseMessaging.deleteInstanceID();
_firebaseMessaging.getToken().then((token) => fcmtoken = token);
}
Hope this works for you! :)
In my case, the problem was on the recipient side, not the sender. If you're sending a message to someone who has not run the app for awhile, then their device token is stale. All they need to do is restart the app.
In your case, did you ensure that when you sent multiple notifications all the devices you messaged were up and running and that the app refreshes the token on startup by calling FirebaseMessaging.getInstance().getToken()?
While searching for the "NotRegistered" issue, we found the following ...
At device end, the generation of device notification token was done by following code once, when user first time starts the app after installation.
RegToken = FirebaseInstanceId.getInstance().getToken(senderId, "FCM"); // Old code
We were using other class derived from "FirebaseMessagingService" to create / receive notifications. But the following method was missing in that class.
// New code
#Override
public void onNewToken(String token) {
Log.d(TAG, "Refreshed token: " + token);
// If you want to send messages to this application instance or
// manage this apps subscriptions on the server side, send the
// Instance ID token to your app server.
sendRegistrationToServer(token);
}
We found that, the above method was called by FCM system in device on every start of App. ( The App was not Uninstalled, still the method was giving different token every time. ) So we called our method 'sendRegistrationToServer(token);' to submit the token to our server along with the 'DeviceId' and other identification data. When we sent notification from php server on this token, it returned 'sent' instead of "NotRegistered".
This error appeared in an Android application when sending request to https://fcm.googleapis.com/fcm/send:
...
"results": [
{
"error": "NotRegistered"
}
]
While the application was working well for some time, and push notifications were delivered, then (probably after reauthorization in the app or reauthorization in Play Market) that error started to show.
If I changed push token (added "1", for instance), then I got another error:
"results": [
{
"error": "InvalidRegistration"
}
]
So, Firebase knew about the push token, but didn't deliver a notification.
I uninstalled the Android application and installed again.
My problem was different then all of the above. The Firebase message that we we're trying exceeded the maximum size of 4Kb. Very small chance this triggers an "NotRegistered". But the problem was that I took this log of a moment the app was probably not installed. So also check the size of the Firebase message.
In our case, this issue appears on iOS when we override a production installation of the app using Xcode "Run" (replaces production app with the debug version in-place).
The app still receives the same registration token, but doesn't accept messages (NotRegistered is returned from the FCM).
We've found out that uninstalling the app from the device, and performing a clean install fixes this issue.
In my case, updating the FCM token for the device worked!
I have a 100 percent solution i had fix recently this issue this
error, occurring because you are sending this notification on a device
which does does not contain your firebase setup api key For example
when you registered user that time user registered from different
firebase setup so your android token was different and your sending
request to other firebase setup for which didn't create android token
whom you trying to send notification(message) so you would have to
make sure your user android token generating from same firebase
project of which project you are using firebase api key
In my case, two cloned emulators are the reason.
I think cloned emulators have same device ID, so firebase think they are same device.
So when one device get a push message, the push token may be removed and return not NotRegistered.
If you are in the similar situation, try to remove the emulator and create new one.
A possible solution can be update user push token.
When the client app is updated (new version), old push token is changed.
I got this error after setting firebase and using app for some time.
I updated google-service.json file (look for new file in the user's personal account firebase) and reinstall app. It helps me.
For iOS, I ran into the same issue. We were only saving the token on didRegisterForRemoteNotificationsWithDeviceToken. As mentioned above, you can lose reference to the token for a variety of reasons.
To fix the "NotRegistered" error, I added the following to App Delegate:
extension AppDelegate: MessagingDelegate {
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
print("Firebase registration token: \(String(describing: fcmToken))")
//Notification setup. Token will be available anywhere
let dataDict: [String: String] = ["token": fcmToken ]
NotificationCenter.default.post(
name: Notification.Name("FCMToken"),
object: nil,
userInfo: dataDict
)
// Send token to application server.
if Auth.auth().currentUser?.uid != nil {
guard let userUid = Auth.auth().currentUser?.uid else { return }
let dataBaseRef = Database.database().reference()
let value: [String : Any] = ["pushToken" : fcmToken]
dataBaseRef.child("Your database path here").updateChildValues(value, withCompletionBlock: { (error, ref) in
if error != nil {
print("Error with storing/updating user token", error?.localizedDescription as Any)
}
})
}
}
}
didReceiveRegistrationToken is called anytime the token is updated.
After uninstalling the app in my device, the error occurred. That was because my code wasn't set up to regenerate a new fcm device token. The firebase documentation for this API recommends to call the method at app start and update your backend (or wherever you're using the tokens). I fixed it with the snippet below:
import {Platform} from 'react-native';
import messaging from '#react-native-firebase/messaging';
useEffect(() => {
requestPermission();
messaging()
.getToken()
.then(async token => {
console.log('_token=>>>', token);
if (token) {
setDeviceToken(token);
// update user realtime fdb with device token and userIdToken
const _authDriverIdRef = firebase
.database()
.ref(`users/${user.uid}`);
_authDriverIdRef.update({
fcmDeviceToken: deviceToken,
userIdToken: await user?.getIdToken(true),
});
}
});
});
const requestPermission = async () => {
return Platform.OS === 'ios' && (await messaging().requestPermission());
};
See if you have uninstalled the app and your device token is modified. Update the device token, and your error will be gone

Push notification is not being recieved on iphone. It is delivered from server aparently. It may be implementation error

I am trying to send push notification to apple's Passbook application on updation of a coupon, in order to update it in PassBook application on device.
According to apple's passbook documentation I am sending an empty push notification but it is not being received on device. I have tried to send with some text in the push notification but results are same.
I am using this PHP library to send push notification.
Here is my implementation which is being called on coupon update action;
// Adjust to your timezone
date_default_timezone_set('Asia/Karachi');
// Report all PHP errors
error_reporting(-1);
//Instantiate a new ApnsPHP_Push object
$push = new ApnsPHP_Push(
ApnsPHP_Abstract::ENVIRONMENT_PRODUCTION,
base_path().'/config/ios-push-notification-certificates/production/ProductionCertificate.pem'
);
// Set the Provider Certificate passphrase
$push->setProviderCertificatePassphrase('mypassphrase');
// Set the Root Certificate Autority to verify the Apple remote peer
$push->setRootCertificationAuthority(base_path().'/config/ios-push-notification-certificates/entrust_root_certificate.pem');
// Connect to the Apple Push Notification Service
$push->connect();
// Instantiate a new Message with a single recipient
$message = new ApnsPHP_Message('b2ae8b68fff1fbbe957b8b8f703744794d89f09d45f69b2d847a26c3b064e268');
// Set a custom identifier. To get back this identifier use the getCustomIdentifier() method
// over a ApnsPHP_Message object retrieved with the getErrors() message.
$message->setCustomIdentifier("Message-Badge-3");
// Set badge icon to "3"
$message->setBadge(3);
// Set a simple welcome text
$message->setText('');
// Play the default sound
$message->setSound();
// Set a custom property
$message->setCustomProperty('acme2', array('bang', 'whiz'));
// Set another custom property
$message->setCustomProperty('acme3', array('bing', 'bong'));
// Set the expiry value to 30 seconds
$message->setExpiry(30);
// Add the message to the message queue
$push->add($message);
// Send all messages in the message queue
$push->send();
// Disconnect from the Apple Push Notification Service
$push->disconnect();
// Examine the error message container
$aErrorQueue = $push->getErrors();
if (!empty($aErrorQueue)) {
print_r($aErrorQueue);
}
And here is the output printed by the library which show message has been sent. It is not print_r($aErrorQueue); output.
I didn't get why I am unable to update the pass automatically or receive the push notification. It is quite new to me this push notification service. Please guide me if I can debug any thing or try something else. My endpoints for apple server are working fine I can install and update the pass manually from passbook.

iOS Notification issue and no error

I have an app built with cordova and pushplugin, i receive the token from the device then i try to send a notification using a php server with the following code:
require_once 'ApnsPHP/Autoload.php';
// Instantiate a new ApnsPHP_Push object
$push = new ApnsPHP_Push(
ApnsPHP_Abstract::ENVIRONMENT_SANDBOX,
'server_certificates.pem'
);
// Set the Root Certificate Autority to verify the Apple remote peer
$push->setRootCertificationAuthority('entrust_root_certification_authority.pem');
// Connect to the Apple Push Notification Service
$push->connect();
// Instantiate a new Message with a single recipient
$message = new ApnsPHP_Message($regid);
// Set a simple welcome text
$message->setText("GELLLOOOOOO !! ");
// Play the default sound
$message->setSound();
// Add the message to the message queue
$push->add($message);
$push->send();
$push->disconnect();
$err = $push->getErrors() ;
echo "<pre>". var_dump($err) . "</pre>" ;
die("{}") ;
this code return no error in $err variable, I have absolutly no clue why this isn't working because it was working fine for a little moment i was able to get notifications on the device with the same code and same certificates and then it just decided to not work anymore.

iOS Notifications push server with php

I have something wrong with my notifications but i can't see where is the problem. I have an app that generates the token successfully, at first I was able to send a notification from my localhost to the device, but after i restored the device and and tested with the new device token to push a simple notification i couldn't get get it to work even though I didn't made any changes to php code nor my app code, here is my php code :
require_once 'ApnsPHP/Autoload.php';
// Instantiate a new ApnsPHP_Push object
$push = new ApnsPHP_Push(
ApnsPHP_Abstract::ENVIRONMENT_SANDBOX,
'server_certificates_bundle_sandbox.pem'
);
// Set the Root Certificate Autority to verify the Apple remote peer
$push->setRootCertificationAuthority('entrust_root_certification_authority.pem');
// Connect to the Apple Push Notification Service
$push->connect();
// Instantiate a new Message with a single recipient
$message = new ApnsPHP_Message($token);
// Set a simple welcome text
$message->setText("GELLLOOOOOO");
// Play the default sound
$message->setSound();
// Add the message to the message queue
$push->add($message);
$push->send();
$push->disconnect();
// Examine the error message container
$aErrorQueue = $push->getErrors();
var_dump($aErrorQueue);
I think it have something to do with certificates but i'm not sure where is the issues since it was working before and there is nothing in $aErrorQueue , just an empty array.

Categories