From the push notification guide, Im noticing that parse recommends setting the device token from within the AppDelegate. Im interested in sending push notifications to certain users, and Im wondering if its possible to move the code for registering a device and their deviceToken within the login code which is found outside of the AppDelegate.
I think you should keep the deviceToken association in the delegate, but after the user logs in, grab the current installation and associate it with the user:
PFInstallation *current = [PFInstallation currentInstallation];
[current setObject:[PFUser currentUser] forKey:#"owner"];
[current saveInBackground];
You can run this code after login/ signup in application
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation setDeviceTokenFromData:sharedInstance.DeviceToken];
[currentInstallation setObject:[PFUser currentUser] forKey:#"user"];
currentInstallation.channels = #[ #"channel" ];
[currentInstallation saveInBackground];
Related
I want to update device token in installation table on parse using iOS.
To save a device token I did:
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation setDeviceTokenFromData:(NSData*)[AppHelper userDefaultsForKey:#"token"]];
[currentInstallation setObject:[PFUser currentUser].objectId forKey:#"user"];
NSArray *channels = [NSArray arrayWithObjects:#"AnyString",nil];
currentInstallation.channels=channels;
[currentInstallation saveInBackground];
I want to update this device token. I know to update token I have to use rest API i.e. https://api.parse.com/1/installations. How to update the row as I also don't have installation id.
Please provide proper syntax.
Write below code in didRegisterForRemoteNotificationsWithDeviceToken method in AppDelegate .
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
PFInstallation *currnentInstallation = [PFInstallation currentInstallation];
[currnentInstallation setDeviceTokenFromData:deviceToken];
[currnentInstallation saveInBackground];
}
For Register user in channels use below code in Login Screen
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
if ([PFUser currentUser].objectId)
{
currentInstallation[#"user"] = [PFUser currentUser];
currentInstallation.channels = #[[NSString stringWithFormat:#"user_%#",[PFUser currentUser].objectId]];
NSLog(#"Saving Installation channel = %#",currentInstallation.channels);
[currentInstallation saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error)
{
NSLog(#"Current installation updated: Error: %#",error);
}];
}
For more details , refer this link https://www.parse.com/docs/ios/guide#push-notifications-installations
In AppDelegate's didRegisterForRemoteNotificationsWithDeviceToken method, set deviceToken to installation table and save device token to NSUserDefaults ,like this:
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation setDeviceTokenFromData:deviceToken];
currentInstallation.channels = #[#"global"];
[currentInstallation saveInBackground];
[[NSUserDefaults standardUserDefaults]setObject:deviceToken forKey:#"deviceToken"];
And on login or signup ,set user like this :
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation setObject:[PFUser currentUser] forKey:#"User"];
[currentInstallation setDeviceTokenFromData:[[NSUserDefaults standardUserDefaults] valueForKey:#"deviceToken"]];
currentInstallation.channels = #[#"global"];
[currentInstallation saveInBackground];
UPDATE:
you need to make additions to installation table. Add column userID to installation and then get query installation table with current user's userID.
You can refer this https://www.parse.com/questions/retrieve-objectid-from-installation-table link for better understanding
Hope it helps :)
I'm trying to register a device in several Parse channels, but does not work and do not know what I'm doing wrong.
In my table Parse does not appear that the device is in these channels
This is executed when you press a button.
[currentInstallation addUniqueObject:#"CocaCola" forKey:#"channels"];
[currentInstallation addUniqueObject:#"Seur" forKey:#"channels"];
[currentInstallation addUniqueObject:#"ADIF" forKey:#"channels"];
[currentInstallation saveInBackground];
Try the following:
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
currentInstallation.channels = #[ #"CocaCola", #"Seur", #"ADIF" ];
[currentInstallation saveInBackground];
Alternatively, look into using subscribeToChannelInBackground
subscribeToChannelInBackground:
Asynchronously subscribes the device to a channel of push notifications.
+ (void)subscribeToChannelInBackground:(NSString *)channel
I'm trying to enable push notifications through parse. The parse notification code works if there is already a user cached and signed into the app. If I logout and try to signup a new user, however, the app crashes and I get an error that states: 'NSInvalidArgumentException', reason: 'Can't use nil for keys or values on PFObject. Use NSNull for values.'...I believe the issue is with the didRegisterForRemoteNotificationsWithDeviceToken method within the app delegate. Because there isn't a currentUser logged in, when the app tries creating a PFInstallation, all of the associating fields are returning nil. I have tried an if statement checking for a currentUser before running the PFInstallation code, but the app still crashes. I need to register for notifications after signup occurs, but I can't figure out how to do that seeing as didRegisterForRemoteNotificationsWithDeviceToken needs to occur in the app delegate. Any advice or solutions are appreciate. My code snippet is below. Thanks!
EDIT: This code works now!
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)newDeviceToken
{
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
if ([PFUser currentUser] != nil)
{
currentInstallation[#"currentUser"]=[PFUser currentUser];
}
else
{
[currentInstallation removeObjectForKey:#"currentUser"];
}
[currentInstallation setDeviceTokenFromData:newDeviceToken];
[currentInstallation saveInBackground];
}
For Sending Push Notifications
- (IBAction)send:(id)sender
{
PFQuery *userQuery = [PFUser query];
[userQuery whereKey:#"objectId" equalTo:self.recipient.objectId];
PFQuery *query = [PFInstallation query];
[query whereKey:#"user" matchesQuery:userQuery];
NSString *sendingUser = self.currentUser.username;
NSString *message = [NSString stringWithFormat:#"from %#: \n %#", sendingUser,self.message.text];
PFPush *push= [[PFPush alloc]init];
[push setQuery:query];
[push setMessage:message];
[push sendPushInBackground];
NSLog(#"Message sent!");
[self dismissViewControllerAnimated:NO completion:nil];
}
You can still register an installation without a current user, but you have to make sure that the user is removed from the registration -
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
// Store the deviceToken in the current installation and save it to Parse.
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
if ([PFUser currentUser] != nil)
{
currentInstallation[#"currentUser"]=[PFUser currentUser];
}
else {
[currentInstallation removeObjectForKey:#"currentUser"];
}
[currentInstallation setDeviceTokenFromData:deviceToken];
[currentInstallation saveInBackground];
}
Then, wherever you handle login/logout events you can update the current installation record. For example -
-(void) loggedIn
{
PFInstallation *currentInstallation=[PFInstallation currentInstallation];
currentInstallation[#"currentUser"]=[PFUser currentUser];
[currentInstallation saveInBackground];
}
-(void) notLoggedIn
{
PFInstallation *currentInstallation=[PFInstallation currentInstallation];
[currentInstallation removeObjectForKey:#"currentUser"];
[currentInstallation saveInBackground];
}
I am using parse rest api from my php app to push to ios app. I can see in parse it has been pused to parse successfully
But how come parse not pushing these notificatioin to ios app?
You can do this by following the below steps:-
1) Register for remote notification from iOS app AppDelegate.m
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation setDeviceTokenFromData:deviceToken];
[currentInstallation saveInBackground];
}
2) Subscribe the UDID to channels - Group channels as per your requirement
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation addUniqueObject:#"ChannelName" forKey:#"channels"];
[currentInstallation saveInBackground];
3) Send Notification to the particular channel from your php app.
I'm trying to enable push notifications through parse. The parse notification code works if there is already a user cached and signed into the app. If I logout and try to signup a new user, however, the app crashes and I get an error that states: 'NSInvalidArgumentException', reason: 'Can't use nil for keys or values on PFObject. Use NSNull for values.'...I believe the issue is with the didRegisterForRemoteNotificationsWithDeviceToken method within the app delegate. Because there isn't a currentUser logged in, when the app tries creating a PFInstallation, all of the associating fields are returning nil. I have tried an if statement checking for a currentUser before running the PFInstallation code, but the app still crashes. I need to register for notifications after signup occurs, but I can't figure out how to do that seeing as didRegisterForRemoteNotificationsWithDeviceToken needs to occur in the app delegate. Any advice or solutions are appreciate. My code snippet is below. Thanks!
EDIT: This code works now!
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)newDeviceToken
{
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
if ([PFUser currentUser] != nil)
{
currentInstallation[#"currentUser"]=[PFUser currentUser];
}
else
{
[currentInstallation removeObjectForKey:#"currentUser"];
}
[currentInstallation setDeviceTokenFromData:newDeviceToken];
[currentInstallation saveInBackground];
}
For Sending Push Notifications
- (IBAction)send:(id)sender
{
PFQuery *userQuery = [PFUser query];
[userQuery whereKey:#"objectId" equalTo:self.recipient.objectId];
PFQuery *query = [PFInstallation query];
[query whereKey:#"user" matchesQuery:userQuery];
NSString *sendingUser = self.currentUser.username;
NSString *message = [NSString stringWithFormat:#"from %#: \n %#", sendingUser,self.message.text];
PFPush *push= [[PFPush alloc]init];
[push setQuery:query];
[push setMessage:message];
[push sendPushInBackground];
NSLog(#"Message sent!");
[self dismissViewControllerAnimated:NO completion:nil];
}
You can still register an installation without a current user, but you have to make sure that the user is removed from the registration -
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
// Store the deviceToken in the current installation and save it to Parse.
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
if ([PFUser currentUser] != nil)
{
currentInstallation[#"currentUser"]=[PFUser currentUser];
}
else {
[currentInstallation removeObjectForKey:#"currentUser"];
}
[currentInstallation setDeviceTokenFromData:deviceToken];
[currentInstallation saveInBackground];
}
Then, wherever you handle login/logout events you can update the current installation record. For example -
-(void) loggedIn
{
PFInstallation *currentInstallation=[PFInstallation currentInstallation];
currentInstallation[#"currentUser"]=[PFUser currentUser];
[currentInstallation saveInBackground];
}
-(void) notLoggedIn
{
PFInstallation *currentInstallation=[PFInstallation currentInstallation];
[currentInstallation removeObjectForKey:#"currentUser"];
[currentInstallation saveInBackground];
}