简体   繁体   中英

Can not register push notification for ios (Azure Mobile app, Node js sdk, ionic 2)

I am working on the Azure mobile app and try to push notification to ios, my app can push notification for android but can not for ios. because in the case ios I cannot register the device to notification hub in the client side, I am facing the issue

在此处输入图片说明

Here is my client code (ionic 2)

initPushNotification(userId = undefined, deviceToken = undefined, installationId = undefined) {
   const options: PushOptions = {
     android: {
       senderID: 'mysender id',
       forceShow: false,
       sound: true
     },
     ios: {
       alert: 'true',
       badge: false,
       sound: 'true'
     },
     windows: {}
   };
   this.platform.ready().then(() => {
     const pushObject: PushObject = this.push.init(options);

     pushObject.on('registration').subscribe((data: any) => {
       let handle = data.registrationId;

       let templateAndroid = {
         body: { data: { message: "{$(message)}", notificationtype: "{$(notificationtype)}" } },
         tags: [userId]
       };

       let templateiOS = {
         body: { aps: { alert: "{$(message)}", notificationtype: "{$(notificationtype)}" } },
         tags: [userId]
       };

       this.client = new WindowsAzure.MobileServiceClient("http://phattifymobileservice.azurewebsites.net");
       if (!deviceToken || (deviceToken !== handle)) {
         if (this.platform.is('ios')) {
           this.typeDevice = 'ios';
           this.client.push.register('apns', handle, { mytemplate: templateiOS }); -----> the error is here
         } else if (this.platform.is('android')) {
           this.typeDevice = 'android';
           this.client.push.register('gcm', handle, { mytemplate: templateAndroid });
         }
         installationId && this.unregisterPush(deviceToken, installationId);
         this.apiProvider.updateDeviceToken(handle, this.client.push.installationId).subscribe(res => {
           console.log('update device token', res);
         })
       }
       console.log('device token -> ' + data.registrationId);
     });
     let me = this;
     pushObject.on('notification').subscribe(data => {
       if (!data.additionalData.foreground) {
         this.events.publish('push:on', { tabIndex: 1 });
       }
     })
     pushObject.on('error').subscribe(error => console.error('Error with Push plugin', error));
   });
 }

i tried many think for fix the issue cors domain, but it still isn't working here is my back end.

file app.js

 app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8080');
        res.setHeader('Access-Control-Allow-Headers', 'Origin, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, X-Requested-With, Date, X-Api-Version, X-Response-Time, X-PINGOTHER, X-CSRF-Token,Authorization, Access-Control-Request-Headers, If-Modified-Since, x-zumo-installation-id, x-zumo-version, zumo-api-version');
        res.setHeader('Access-Control-Allow-Methods', 'GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS');
        res.setHeader('Access-Control-Expose-Headers', 'X-Api-Version, X-Request-Id, X-Response-Time');
        res.setHeader('Access-Control-Max-Age', '1000');
        res.setHeader('Access-Control-Allow-Credentials', 'true');
        next();
    });

file push notification

var payload = {
        message: JSON.parse(msg.Content).Content,
        notificationType: config.get("notificationType")
    };


    context.push.send(Id, payload, function (error) {
        if (!error) {
            //notification sent
            console.log(error);
        }
    });

Push notification for Android -----> working well

Push notification for ios-----> error

I don't know why I got this error, please help me out of this error

after tried some test, there are clues

My app is using the socket for the chat function so I need to enable the CORS. I tried to comment the CORS in code and log into Azure portal and set CORS under "API > CORS" of My mobile app then the Client IOS can register to notification hub so i can push notification, but the socket raise up to me 2 errors

  1. cannot use wildcard in access-control-allow-origin when credentials flag is true

  2. failed to load resource: cannot use wildcard in access-control-allow-origin when credentials flag is true so

Update

mobileApp.tables.initialize()
    .then(function () {
    app.use(mobileApp);    // Register the Azure Mobile Apps middleware
    var httpChat = require('http').Server(app);
    var io = require('socket.io')(httpChat);
    io.set('origins', 'http://localhost:8080');
    require('./api/chat/service/Chat.js')(app, io, multer, uniqid, mkdirp);
    require('./api/chat/service/Room.js')(app, io, multer, uniqid, mkdirp);
    httpChat.listen(process.env.PORT || 3000);  // Listen for requests
});

According to your description, you are using App Service Push which would expose the below API endpoint(s) for the client to device registration and internally invoke the corresponding Azure Notification Hubs for registration management.

//Create Or Update Installation
PUT https://{your-mobile-app-name}.azurewebsites.net/push/installations/{InstallationId}

//Delete Installation
DELETE https://{your-mobile-app-name}.azurewebsites.net/push/installations/{InstallationId}

For your error response, it's talking about CORS. I would recommend you could try to comment out the related code for CORS settings, then log into Azure portal and set CORS under "API > CORS" of your mobile app to narrow down this issue. Moreover, since Push notification for Android is ok, you could collect the network traces and compare the requests between pushing for Android and iOS to troubleshot this issue by yourself.


UPDATE:

You could follow CORS not allowed when using socket.io and Socket.io + Node.js Cross-Origin Request Blocked to write your code as follows:

io.set('origins', 'http://localhost:8080');

res.header("Access-Control-Allow-Origin", "http://localhost:8080");
res.header('Access-Control-Allow-Credentials', true);

Or you could just leverage cors package to enable CORS.


UPDATE2:

For your issue, I did some test on my side. I found that if you set CORS under "API > CORS", then you would get the following similar error:

Failed to load http://brucemobile.azurewebsites.net/socket.io/?EIO=3&transport=polling&t=MIIOCpK : The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. Origin ' http://localhost ' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

For your issue, you need to implicitly set it in your code as follows:

 app.use(function (req, res, next) { res.setHeader('Access-Control-Allow-Origin', 'http://localhost'); next(); }); 

Note: You do not need to manually set origins for Socket.io, any origins would be allowed by default. Details you could refer to here .

For registering the registration, I did not test the full process, I just sent a get request as follows to check whether the CORS has been effected or not.

 http://{your-mobile-app-name}.azurewebsites.net/push/installations/{guid} 

TEST:

在此处输入图片说明

Moreover, you could follow my testing website: http://brucemobile.azurewebsites.net/index.html , you could save the html to your local side and test it with my mobile app backend.

Backend app.js

 // This is a base-level Azure Mobile App SDK. var express = require('express'), azureMobileApps = require('azure-mobile-apps'); // Set up a standard Express app var app = express(); app.use(function (req, res, next) { res.setHeader('Access-Control-Allow-Origin', 'http://localhost'); next(); }); var mobileApp = azureMobileApps({ // Explicitly enable the Azure Mobile Apps home page homePage: true, // Explicitly enable swagger support. UI support is enabled by // installing the swagger-ui npm module. swagger: true, // App will use MS_SqliteFilename or MS_TableConnectionString to choose the SQLite or SQL data provider data: { dynamicSchema: true } }); // Import the files from the tables directory to configure the /tables endpoint mobileApp.tables.import('./tables'); // Import the files from the api directory to configure the /api endpoint mobileApp.api.import('./api'); // Initialize the database before listening for incoming requests // The tables.initialize() method does the initialization asynchronously // and returns a Promise. mobileApp.tables.initialize() .then(function () { app.use(mobileApp); // Register the Azure Mobile Apps middleware var httpServer=require('http').Server(app); var io=require('socket.io')(httpServer); //io.set('origins', 'abc'); io.on('connection', function(socket){ socket.on('user message', function(msg){ console.log('[client]: ' + msg); socket.emit('server message','[server '+new Date().toISOString()+']: '+msg); }); socket.on('disconnect', function(){ console.log('user disconnected'); }); }); httpServer.listen(process.env.PORT || 3000); // Listen for requests }); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM