我正在尝试学习使用azure移动应用程序,但我在使用NotificationHub时遇到了严重问题。我有一个Imagine订阅Azure。我用azure后端创建了一个 android 移动应用程序。我在azure门户网站上创建了与azure移动应用程序关联的通知中心。 要在通知中心注册应用程序,我使用了本教程中的代码:
通过使用他们的Google帐户,微软帐户或Facebook帐户,>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
但问题仍然存在。希望可以有人帮帮我。感谢。
答案 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);