使用azure通知中心

时间:2016-11-26 08:50:33

标签: android node.js azure azure-mobile-services azure-notificationhub

我正在尝试学习使用azure移动应用程序,但我在使用NotificationHub时遇到了严重问题。我有一个Imagine订阅Azure。我用azure后端创建了一个 android 移动应用程序。我在azure门户网站上创建了与azure移动应用程序关联的通知中心。 要在通知中心注册应用程序,我使用了本教程中的代码:

https://docs.microsoft.com/en-gb/azure/notification-hubs/notification-hubs-android-push-notification-google-fcm-get-started

通过使用他们的Google帐户,微软帐户或Facebook帐户, 用户在azure后端上进行身份验证。新用户通过以下节点js代码为表脚本Users.js插入表用户。我想要一个推送通知来欢迎新用户

var azureMobileApps = require('azure-mobile-apps');
var logger = require('azure-mobile-apps/src/logger');
var table = azureMobileApps.table();

table.access = 'authenticated';

/**
* Adds the email address from the claims to the context item - used for
* insert operations
* @param {Context} context the operation context
* @returns {Promise} context execution Promise
*/
function addEmailToContext(context) {
    /*
    * Getting claim fields
    */
    return context.user.getIdentity().then((data) => {
       if( data.microsoftaccount != undefined){
            context.item.email = data.microsoftaccount.claims.emailaddress;
            context.item.name = data.microsoftaccount.claims.givenname;
            context.item.surname = data.microsoftaccount.claims.surname;           
       }
       if( data.google != undefined){
            context.item.email = data.google.claims.emailaddress;
            context.item.name = data.google.claims.givenname;
            context.item.surname = data.google.claims.surname;
            context.item.picture_url = data.google.claims.picture;
       }
       if( data.facebook != undefined){
            context.item.email = data.facebook.claims.emailaddress;
            context.item.name = data.facebook.claims.givenname;
            context.item.surname = data.facebook.claims.surname;
       }

       logger.info('[tables/Users.js] --> NEW USER REGISTERED:'
                +'\n\t Name:'+context.item.name
                +'\n\t Surname:'+context.item.surname
                +'\n\t Email:'+context.item.email);


    // Execute the insert.  The insert returns the results as a Promise,
    // Do the push as a post-execute action within the promise flow.
    return context.execute()
        .then(function (results) {
            // Only do the push if configured
            if (context.push) {
                // Mobile Apps adds a user tag when registering for push notifications

                 // Define the GCM payload.
                 var payload = {
                     "data": {
                         "message": 'Welcome '+context.item.username
                     }
                 };       

                context.push.gcm.send(context.user.id, payload, function (error) {
                    if (error) {
                        logger.error('Error while sending push notification: ', error);
                    } else {
                        logger.info('Push notification sent successfully!');
                    }
                });
            }
            // Don't forget to return the results from the context.execute()
            return results;
        })
        .catch(function (error) {
            logger.error('Error while running context.execute: ', error);
        });
    });
}

// CREATE - add or overwrite the authenticated user
table.insert(addEmailToContext);

module.exports = table;

根据"如何:使用标签向经过身份验证的用户发送推送通知"在How to use the Azure Mobile Apps Node.js SDK

的教程中

"当经过身份验证的用户注册推送通知时,用户ID标记会自动添加到注册。 " 所以在Users.js中,按照本教程的建议,我编写了以下代码,将推送通知发送给用户。

context.push.gcm.send(context.user.id, payload, function (error) {
                    if (error) {
                        logger.error('Error while sending push notification: ', error);
                    } else {
                        logger.info('Push notification sent successfully!');
                    }
                });

使用此代码,推送通知会成功发送,但设备不会收到任何通知。如果我使用 null而不是context.user.id,则所有设备都会正确接收推送通知

context.push.gcm.send(null, payload, function (error) {
                    if (error) {
                        logger.error('Error while sending push notification: ', error);
                    } else {
                        logger.info('Push notification sent successfully!');
                    }
                });

当用户注册到集线器时,我还尝试调用以下自定义API来创建标记。调用的API如下:

var logger = require('azure-mobile-apps/src/logger');

exports.post = function(req, res) {
    logger.info('[api/registerTag.js] --> Invoked');

        // Get the notification hub used by the mobile app.
        var push = req.azureMobile.push,
            installationId = req.get('X-ZUMO-INSTALLATION-ID'),
            tags = req.body.tag.toString();



        // Define an update tags operation.
        var updateOperation = [{
            "op": "add",
            "path": "/tags",
            "value": tags
        }];

        // Update the installation to add the new tags.
        push.patchInstallation(installationId, updateOperation, function(error) {
            if(error){
                logger.error('[api/registerTag.js] --> An error occurred while adding'
                            +'the following tags: \n\t'+tags, error);
                res.status(error.statusCode).send(error.detail);
            } else {
                logger.info('[api/registerTag.js] --> The following tags have been added' 
                            +'to the Notification Hub: \n\t'+tags, error);
                res.status(200).send(tags);
            }
        });
};

在控制台上打印标签已成功添加。但是,如果我然后像这样修改Users.js代码:

...
// Only do the push if configured
            if (context.push) {
                // Mobile Apps adds a user tag when registering for push notifications
                var userTag = '_UserId:' + context.user.id;
                logger.info("TAG   "+userTag);

                 // Define the GCM payload.
                 var payload = {
                     "data": {
                         "message": 'Welcome '+context.item.username
                     }
                 };       

                context.push.gcm.send(userTag, payload, function (error) {
                    if (error) {
                        logger.error('Error while sending push notification: ', error);
                    } else {
                        logger.info('Push notification sent successfully!');
                    }
                });
            }
...

再没有收到任何内容。我还尝试使用移动应用的推送部分自动添加标签或添加标签,如图所示:

图片链接:i.stack.imgur.com/KBvQI.png

但问题仍然存在。希望可以有人帮帮我。感谢。

1 个答案:

答案 0 :(得分:0)

经过多次测试,我成功地重现了你的问题并遇到了同样的问题。为了达到您的要求,我在Android客户端进行了一些修改:

1,MainActivity类中的缓存身份验证用户。以下是我的代码段。有关详细信息,请参阅Updating an MVC Partial View with Ajax

public static final String SHAREDPREFFILE = "temp";    
public static final String USERIDPREF = "uid";    
public static final String TOKENPREF = "tkn";

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    try {
        // Create the Mobile Service Client instance, using the provided Mobile Service URL and key
        mClient = new MobileServiceClient(
                "https://yourwebsitename.azurewebsites.net",
                this).withFilter(new ProgressFilter());

        // Extend timeout from default of 10s to 20s
        mClient.setAndroidHttpClientFactory(new OkHttpClientFactory() {
            @Override
            public OkHttpClient createOkHttpClient() {
                OkHttpClient client = new OkHttpClient();
                client.setReadTimeout(20, TimeUnit.SECONDS);
                client.setWriteTimeout(20, TimeUnit.SECONDS);
                return client;
            }
        });

        authenticate();

    } catch (MalformedURLException e) {
        createAndShowDialog(new Exception("There was an error creating the Mobile Service. Verify the URL"), "Error");
    } catch (Exception e){
        createAndShowDialog(e, "Error");
    }
}

private void authenticate() {
    // We first try to load a token cache if one exists.
    if (loadUserTokenCache(mClient)) {
        createTable();
        register();
    }
    // If we failed to load a token cache, login and create a token cache
    else {
        // Login using the Google provider.
        ListenableFuture<MobileServiceUser> mLogin = mClient.login(MobileServiceAuthenticationProvider.Google);

        Futures.addCallback(mLogin, new FutureCallback<MobileServiceUser>() {
            @Override
            public void onFailure(Throwable exc) {
                createAndShowDialog("You must log in. Login Required", "Error");
            }
            @Override
            public void onSuccess(MobileServiceUser user) {
                createAndShowDialog(String.format("You are now logged in - %1$2s", user.getUserId()), "Success");
                cacheUserToken(mClient.getCurrentUser());
                createTable();
                register();
            }
        });
    }
}

private void cacheUserToken(MobileServiceUser user) {
    SharedPreferences prefs = getSharedPreferences(SHAREDPREFFILE, Context.MODE_PRIVATE);
    Editor editor = prefs.edit();
    editor.putString(USERIDPREF, user.getUserId());
    editor.putString(TOKENPREF, user.getAuthenticationToken());
    editor.commit();
}

private void register() {
    NotificationsManager.handleNotifications(this, NotificationSettings.SenderId, MyHandler.class);
    registerWithNotificationHubs();
}

2,在RegistrationIntentService类中使用以下代码替换regID = hub.register(FCM_token).getRegistrationId();

regID = hub.register(FCM_token, prefs.getString("uid", "")).getRegistrationId();

3,确保将以下行添加到onHandleIntent方法中的第一行。

SharedPreferences prefs = getSharedPreferences("temp", Context.MODE_PRIVATE);