im trying to use the generic push for my app. it works on android but on ios i get the error msg: no valid aps-environment
i have added support to push notifications in apple provisioning
profile
i created and downloaded the provisioning profile after enabling the push
i have <key>aps-environment</key> in mobileprovision
i have installed the mobile provision and app on my phone
i have checked and tested every solution
my config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<widget xmlns = "http://www.w3.org/ns/widgets"
xmlns:gap = "http://phonegap.com/ns/1.0"
id = "---.-------.-----"
versionCode="10"
version = "1.1.0">
<!-- versionCode is optional and Android only -->
<name>PhoneGap push Example</name>
<description>
An example for phonegap build docs.
</description>
<author href="http://-----------" email="---------------">------</author>
<access origin="*" />
<!--DEVICE FEATURES ACCESS-->
<feature name="http://api.phonegap.com/1.0/camera"/>
<feature name="http://api.phonegap.com/1.0/file"/>
<feature name="http://api.phonegap.com/1.0/geolocation"/>
<feature name="http://api.phonegap.com/1.0/media"/>
<feature name="http://api.phonegap.com/1.0/network"/>
<feature name="http://api.phonegap.com/1.0/notification"/>
<gap:plugin name="GenericPush" /> <!-- latest release -->
</widget>
my js
<script type="text/javascript" charset="utf-8" src="phonegap.js"></script>
<script type="text/javascript" charset="utf-8" src="jquery_1.5.2.min.js"></script>
<script type="text/javascript" src="PushNotification.js"></script>
<script type="text/javascript">
var pushNotification;
function onDeviceReady() {
$("#app-status-ul").append('<li>deviceready event received</li>');
pushNotification = window.plugins.pushNotification;
if (device.platform == 'android' || device.platform == 'Android') {
pushNotification.register(successHandler, errorHandler, {"senderID":"661780372179","ecb":"onNotificationGCM"});
} else {
pushNotification.register(tokenHandler, errorHandler, {"badge":"true","sound":"true","alert":"true","ecb":"onNotificationAPN"});
}
}
// handle APNS notifications for iOS
function onNotificationAPN(event) {
if (event.alert) {
$("#app-status-ul").append('<li>push-notification: ' + event.alert + '</li>');
navigator.notification.alert(event.alert);
}
if (event.sound) {
var snd = new Media(event.sound);
snd.play();
}
if (event.badge) {
pushNotification.setApplicationIconBadgeNumber(successHandler, event.badge);
}
}
// handle GCM notifications for Android
function onNotificationGCM(e) {
$("#app-status-ul").append('<li>EVENT -> RECEIVED:' + e.event + '</li>');
switch( e.event )
{
case 'registered':
if ( e.regid.length > 0 )
{
$("#app-status-ul").append('<li>REGISTERED -> REGID:' + e.regid + "</li>");
// Your GCM push server needs to know the regID before it can push to this device
// here is where you might want to send it the regID for later use.
console.log("regID = " + regID);
}
break;
case 'message':
$("#app-status-ul").append('<li>MESSAGE -> MSG: ' + e.message + '</li>');
$("#app-status-ul").append('<li>MESSAGE -> MSGCNT: ' + e.msgcnt + '</li>');
break;
case 'error':
$("#app-status-ul").append('<li>ERROR -> MSG:' + e.msg + '</li>');
break;
default:
$("#app-status-ul").append('<li>EVENT -> Unknown, an event was received and we do not know what it is</li>');
break;
}
}
function tokenHandler (result) {
$("#app-status-ul").append('<li>token: '+ result +'</li>');
// Your iOS push server needs to know the token before it can push to this device
// here is where you might want to send it the token for later use.
}
function successHandler (result) {
$("#app-status-ul").append('<li>success:'+ result +'</li>');
}
function errorHandler (error) {
$("#app-status-ul").append('<li>error:'+ error +'</li>');
}
document.addEventListener('deviceready', onDeviceReady, true);
</script>
<div id="app-status-div">
<ul id="app-status-ul">
<li>Cordova PushNotification Plugin Demo</li>
</ul>
</div>
According to the Phonegap Build community forums, you need to use a distribution provision certificate for the APS registration to work : http://community.phonegap.com/nitobi/topics/ios_problem_with_push_notification_plugin_for_phonegap_build
Some people have succeeded after switching to production certificates.
However, I have the same problem and still cannot get it working with production certificates.
after long research and trial and error. i found out that i need to use:
on IOS (adhoc provision profile) and on push server(production aps cert and key)
Related
The code I have used to work on both Android and IOS, until I had to make the IOS version on ionic use WKWebViewOnly.
This is the code that was working on IOS (still works on Android):
var type = window.PERSISTENT;
var size = 50*1024*1024; // 50MB
window.requestFileSystem(type, size, successCallback, errorCallback);
function successCallback(fs) {
window.resolveLocalFileSystemURL(app.folder, function(dirEntry) {
dirEntry.getFile(mix_name, {create: true}, function(fileEntry) {
fileEntry.createWriter(function(fileWriter) {
fileWriter.onwriteend = function(e) {
alert('Write success');
};
fileWriter.onerror = function(e) {
alert('Write failed: ' + e.toString());
};
var oReq = new XMLHttpRequest();
// Make sure you add the domain name to the Content-Security-Policy <meta> element.
oReq.open("GET", "https://domain-to-get-file.com/path/to/file.mp3", true);
// Define how you want the XHR data to come back
oReq.responseType = "blob";
oReq.onload = function (oEvent) {
var blob = oReq.response; // Note: not oReq.responseText
blob = blobToFile(blob, fileName);
fileWriter.write(blob);
};
oReq.send(null);
}, errorCallback);
}, errorCallback);
}, errorCallback);
}
function errorCallback(error) {
alert("ERROR: " + error.code)
}
function blobToFile(theBlob, fileName) {
// A Blob() is almost a File() - it's just missing the two properties below which we will add
theBlob.lastModifiedDate = new Date();
theBlob.name = fileName;
return theBlob;
}
In my index.html I have the meta tag:
<meta http-equiv="Content-Security-Policy" content="
default-src * data: cdvfile: gap: blob:;
script-src 'self' 'unsafe-inline' *.domain-to-get-file.com;
style-src 'self' 'unsafe-inline';">
And the plugins I have used are:
<plugin name="cordova-plugin-wkwebview-engine" source="npm" />
<plugin name="cordova-plugin-wkwebview-file-xhr" spec="~2.1.4" />
Works fine on Android but not on IOS 13.
I think i'm missing a security thing, but I have no idea how to fix that.
Thanks :)
This was a miss leading issue, but for anyone stumbling upon it.
The fix was to switch from using XMLHttpRequest to Fetch: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
I had no clue about Fetch until I saw this video: https://www.youtube.com/watch?v=tc8DU14qX6I&list=PLRqwX-V7Uu6YxDKpFzf_2D84p0cyk4T7X
and you will also need this: https://www.youtube.com/watch?v=zswi0cPMxsU to solve the CORS issue
I also did removed the plugins:
<plugin name="cordova-plugin-wkwebview-engine" source="npm" />
<plugin name="cordova-plugin-wkwebview-file-xhr" spec="~2.1.4" />
and adding this all-in-one plugin seemed to fix the issue.
https://www.npmjs.com/package/cordova-plugin-wkwebview-ionic-xhr
Added these two preferences in the ios platform in config.xml
<preference name="allowFileAccessFromFileURLs" value="true" />
<preference name="allowUniversalAccessFromFileURLs" value="true" />
I'm trying to communicate from ionic 1 to ios swift native using custom cordova plugin for that I developed a plugin as per https://moduscreate.com/blog/writing-a-cordova-plugin-in-swift-for-ios/ this doc. but I'm not able to communicate. I'm getting:
-[CDVCommandQueue executePending] [Line 142] FAILED pluginJSON = ["LiveConnectCordova486334569","LiveConnectCordova","echo",["jai"]]
plugin.xml
<?xml version='1.0' encoding='utf-8'?>
<plugin id="com-fibase-ionic-ios-multivideo" version="0.0.1"
xmlns="http://apache.org/cordova/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android"> .
<name>LiveConnectCordova</name>
<platform name="ios">
<config-file parent="/*" target="config.xml">
<feature name="LiveConnectCordova">
<param name="ios-package" value="LiveConnectCordova" />
</feature>
</config-file>
<js-module name="LiveConnectCordova" src="www/LiveConnectCordova.js">
<clobbers target="LiveConnectCordova" />
</js-module>
<source-file src="src/ios/LiveConnectCordova.swift" />
<dependency id="cordova-plugin-add-swift-support" version="1.7.2"/>
</platform>
plugin.js
var exec = require('cordova/exec');
exports.coolMethod = function (arg0, success, error) {
exec(success, error, 'LiveConnectCordova', 'echo', [arg0]);
};
myswift class
#objc(LiveConnectCordova) class LiveConnectCordova : CDVPlugin {
func echo(command: CDVInvokedUrlCommand) {
var pluginResult = CDVPluginResult(
status: CDVCommandStatus_ERROR
)
let msg = command.arguments[0] as? String ?? ""
if msg.characters.count > 0 {
pluginResult = CDVPluginResult(
status: CDVCommandStatus_OK,
messageAs: msg
)
}
self.commandDelegate!.send(
pluginResult,
callbackId: command.callbackId
)
}
}
You need to update your LiveConnectCordova.js file code as mention below.
var exec = require('cordova/exec');
exports.echo = function (arg0, success, error) {
exec(success, error, 'LiveConnectCordova', 'echo', [arg0]);
};
As you are calling echo method from your Ionic code.
Also Call plugin method like below.
window["LiveConnectCordova"].echo(
param,
function(res) {
console.log("Response :", res);
},
function(err) {
console.log("Error :", err);
}
);
Try above call in your app.
Hope this will helps!
I've created a cordova project with Visual Studio Code. I'm using this plugin:
phonegap-plugin-push and I've follow the instructions.
I need to use notifications. I'm using Firebase and I've downloaded google-services.json, put it in my root, ran on Android and tested from Firebase cloud messaging. Everything works.
The problem: iOS. I've downloaded GoogleService-Info.plist, put on my root project and root platform ios.
Downloaded the p8 certificates from apple developer console and put on Firebase console:
So, when I launch this on index.js, ondeviceready:
onDeviceReady: function() {
this.receivedEvent('deviceready');
//alert("ciao");
app.push = PushNotification.init({
"android": {
"senderID": "xxxx"
},
"ios": {
"senderID": "xxxx",
"sound": true,
"vibration": true,
"badge": true
},
"windows": {}
});
app.push.on('registration', function(data) {
alert(data.registrationId);
console.log("registration event: " + data.registrationId);
document.getElementById("regId").innerHTML = data.registrationId;
var oldRegId = localStorage.getItem('registrationId');
if (oldRegId !== data.registrationId) {
// Save new registration ID
localStorage.setItem('registrationId', data.registrationId);
// Post registrationId to your app server as the value has changed
}
});
app.push.on('notification', function(data) {
console.log('notification event');
alert("qualcosa ricevuto: " + data.message + data.title);
});
app.push.on('error', function(e) {
//console.log("push error = " + e.message);
alert("push error = " + e.message);
});
}
I receive the token on my iOS device (iPad & iPhone), but when I try to test it from Firebase, I can't see my devices registered token.
Why? What I'm doing wrong?
I assume you are using the latest version of cordova-plugin-push (v2.2.3)?
Did you include the following in Cordova's config.xml?
<platform name="ios">
<resource-file src="GoogleService-Info.plist" />
</platform>
Failing this please check the value of data.registrationType in your .on('registration') callback. The value should be FCM. If it's returning APNS then the registrationId will be a raw APNs token, not a Firebase token, in which case something in your configuration is amiss.
I am new in developing on PhoneGap Build. While testing some basic app functionalities I experience a timeout problem when doing a simple geolocation request on my Iphone 6 / IOS 10 / PhoneGap Build 6.3.0.
After re-installing the app I start it and initiate the geolocation by onclick -> geolocation().
Only when I turn the app to the background, I receive the IOS request to allow the location request (should come when I first do the onclick -> geolocation while having the app in the foreground).
Sometimes I get a geolocation result after a long time, sometimes not. I've tried all possible combinations on the three PositionOptions.
When I ask the Google Maps app it shows me the location immediately.
Any idea what I am doing wrong?
Thank you, Kim
function do_geolocation(){
alert('do geoloc');
navigator.geolocation.getCurrentPosition(geo_onSuccess, geo_onError, {maximumAge:120000, enableHighAccuracy:false} );
}
onclick=do_geolocation();
function geo_onSuccess(position){
alert('Latitude: ' + position.coords.latitude + '\n' +
'Longitude: ' + position.coords.longitude + '\n' +
'Altitude: ' + position.coords.altitude + '\n' +
'Accuracy: ' + position.coords.accuracy + '\n' +
'Altitude Accuracy: ' + position.coords.altitudeAccuracy + '\n' +
'Heading: ' + position.coords.heading + '\n' +
'Speed: ' + position.coords.speed + '\n' +
'Timestamp: ' + position.timestamp + '\n');
var arr = new Array();
arr['lat'] = position.coords.latitude;
arr['lng'] = position.coords.longitude;
var x = new Date();var cb = x.getTime();
}
function geo_onError(position){
alert('code: '+error.code+'\nmessage: '+error.message+'\n');
return false;
}
<?xml version="1.0" encoding="UTF-8" ?>
<widget xmlns = "http://www.w3.org/ns/widgets"
xmlns:gap = "http://phonegap.com/ns/1.0"
id = "de.vvvvvv.secapp"
versionCode = "10"
version = "1.0.0" >
<!-- versionCode is optional and Android only -->
<name>vvvvvvv</name>
<description>
vvvvvvvvvvvv
</description>
<author href="http://vvvvvvv.de" email="info#vvvvvv.de">
Kim
</author>
<plugin name="cordova-plugin-geolocation" spec="2.4.1" />
<plugin name="cordova-plugin-whitelist" spec="1.3.1" />
<access origin="*"/>
<allow-intent href="http://*/*"/>
<allow-intent href="https://*/*"/>
<preference name="orientation" value="portrait" />
<!-- https://makeappicon.com/ios10icon -->
<icon src="res/icons/ios/Icon-App-20x20#2x.png" platform="ios" width="20" height="20" />
<icon src="res/icons/ios/Icon-App-20x20#3x.png" platform="ios" width="40" height="40" />
...
Only when I turn the app to the background, I receive the IOS request to allow the location request (should come when I first do the onclick -> geolocation while having the app in the foreground).
The activation only on backgrounding the app sounds sympomatic of a Content-Security-Policy issue (here's another example).
To resolve, ensure that your Content-Security-Policy meta tag contains gap://ready and file: entries for default-src. For example:
<meta http-equiv="Content-Security-Policy" content="default-src * gap://ready file:; style-src 'self' 'unsafe-inline'; img-src 'self' data:; script-src * 'unsafe-inline' 'unsafe-eval'">
Sometimes I get a geolocation result after a long time, sometimes not. I've tried all possible combinations on the three PositionOptions.
Setting maximumAge to 120000 means a position up to 2 minutes old (cached by the OS) can be used. To force a fresh position, set it to zero:
{
enableHighAccuracy: false
maximumAge: 0,
timeout: 2000
}
If setting enableHighAccuracy to true, this engages GPS hardware to get a lock, so set a sufficient timeout to allow it to lock enough satellites:
{
enableHighAccuracy: true
maximumAge: 0,
timeout: 30000
}
For a full explanation of PositionOptions, see the Mozilla docs
I'm trying to upload a video to a server in PhoneGap. The code is running in terms of opening the camera dialog and recording the video, but then the JS in the index.html file requires use of the FileTransfer plugin.
Adding this plugin from the phonegap command line results in the following error...
/platforms/ios/ManUtd/Plugins/org.apache.cordova.file-transfer/CDVFileTransfer.m:23:9: 'CDVLocalFilesystem.h' file not found
The html file is the documented code from the PhoneGap website
<!DOCTYPE html>
<html>
<head>
<title>Capture Video</title>
<script type="text/javascript" charset="utf-8" src="cordova.js"></script>
<script type="text/javascript" charset="utf-8">
// Called when capture operation is finished
//
function captureSuccess(mediaFiles) {
var i, len;
for (i = 0, len = mediaFiles.length; i < len; i += 1) {
uploadFile(mediaFiles[i]);
}
}
// Called if something bad happens.
//
function captureError(error) {
var msg = 'An error occurred during capture: ' + error.code;
navigator.notification.alert(msg, null, 'Uh oh!');
}
// A button will call this function
//
function captureVideo() {
// Launch device video recording application,
// allowing user to capture up to 2 video clips
navigator.device.capture.captureVideo(captureSuccess, captureError, {limit: 2});
}
// Upload files to server
function uploadFile(mediaFile) {
var ft = new FileTransfer(),
path = mediaFile.fullPath,
name = mediaFile.name;
ft.upload(path,
"http://my.domain.com/upload.php",
function(result) {
console.log('Upload success: ' + result.responseCode);
console.log(result.bytesSent + ' bytes sent');
},
function(error) {
console.log('Error uploading file ' + path + ': ' + error.code);
},
{ fileName: name });
}
</script>
</head>
<body>
<button onclick="captureVideo();">Capture Video</button> <br>
</body>
</html>
I have run both these commands and both result in the code breaking
$ phonegap local plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-file.git
$ phonegap local plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer.git
I am targeting iOS only at the moment
This appears to be related to the whole PhoneGap/Cordova thing.
Creating a new project using Cordova instead of PhoneGap, has sorted the problem. It appears as if the FileTransfer API is broken if you start an app using PhoneGap.