Sending Push Notification from mobile to particular user using parse [Parse IOS] - ios

I have saved user pointer in instalation class. Web backend shows 0 subscribers
I am sending notification using below code
PFQuery *qry = [PFUser query];
[qry getObjectWithId:friendObject.objectId]; //friend object is ok like #"Fefl5x7nhl"
PFQuery *pushQuery = [PFInstallation query];
[pushQuery whereKey:#"user" matchesQuery:qry];
// Send push notification to query
PFPush *push = [[PFPush alloc] init];
NSString *msgString=[NSString stringWithFormat:#"%# :%#",
[newMessage objectForKey:#"userName"],
tfEntry.text];
[push setQuery:pushQuery]; // Set our Installation query
NSDictionary *data = [NSDictionary dictionaryWithObjectsAndKeys:
msgString, #"alert",
#"ursound.caf", #"sound",
#"Increment", #"badge",
// #"Optionally a type was set", #"type",
nil];
[push setData:data];
[push sendPushInBackground];
My installation class does have this user pointer (friend object) and logically it should be receiver of the notification .
AM i missing something? any suggestion would be great . Thanks for your valuable time

As long as you have a column on the Installation class called user that is of type Pointer<My_User> and you've actually populated it, your code should work.
There's a section in the Push Notification documentation that talks about adding data to the Installation class:
https://parse.com/docs/push_guide#sending-queries/iOS

Related

Parse Push Notifications: User to User

Hi I'm making a messaging app that uses the internet to send messages. I need to give a notification from user a to user b.
I use this code:
if (toUser!= nil){
parseMessage[#"toUser"]=toUser;
//PFPush *push = [[PFPush alloc] init];
// [push setQuery://whatshouldiputhere?];
// [push setMessage:[NSString stringWithFormat: #"New Message from %#!", [PFUser currentUser].username]];
// [push sendPushInBackground];
}
This code is executed when the message is being sent. This just doesn't work. What am I doing wrong? Could you please help me?
Thanks for any help.
Sending Push Notifications from User to User are quite similar to using channels, first you have to do a query to find the user then pass that query into the push notification.
So for example:
User A sends User B a message, you have to do a query to find User B in your backend. You can do that many ways, using channels, arrays etc, but for this example I will use an objectId:
-(void)sendPushNotificationToUserBWithObjectId:(NSString *)objectId {
// Build a query that matches user B's objectId (note you would have to save User B's objectId or retrieve it from a different query
PFQuery *subQuery = [PFUser query];
[subQuery whereKey:#"objectId" equalTo:objectId];
// Build the actual push notification from targeted query
PFQuery *finalQuery = [PFInstallation query];
// only return Installations that belong to a User that matches the subQuery & 'toUser' is objectId
[finalQuery whereKey:toUser matchesQuery:innerQuery];
// Send the notification.
PFPush *push = [[PFPush alloc] init];
[push setQuery:finalQuery];
[push setMessage:#"Message"];
[push sendPushInBackground];
}
You would call it at any time like this:
[self sendPushNotificationToUserBWithObjectId:#"xVyWO18"];
where #"xVyWO18" is User B's objectId

Sending push notification to all users in query

I am creating an app that uses Parse cloud. I am trying to send a message from a user to all others. After writing the message in a textfield and pressing send, the delegate calls the following method and the push is handled as shown below:
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
//hide keyboard
[textField resignFirstResponder];
NSString *message = self.broadcastText.text;
//create a user query
PFQuery *query = [PFUser query];
PFUser *current = [PFUser currentUser];
NSString *currentUsername = current[#"username"];
[query whereKey:#"username" notEqualTo:currentUsername];
//send push in background
PFPush *push = [[PFPush alloc] init];
[push setQuery:query];
[push setMessage:message];
[push sendPushInBackground];
//clear text field
textField.text = #"";
return YES;}
What's happening is when I send the message, the sender (in this case me) is receiving the push notification as well. What I tried to do is get the current user's username and then create a user query that queries for all users whose usernames are not equal to the current user's username.
However, it didn't work, the message was also being sent to all users including the sender.
Note: I also tried using [query whereKey:#"username" notEqualTo:currentUsername]; just for debugging, and when I try to send the message, neither the sender nor any other device receives it. (when actually no one should receive it except the sender).
Any help would be greatly appreciated. Thank you.
Your problem is that a PFPush can't take any query, it needs a PFInstallation query. When you store your PFInstallation for each user, you could add a field that points to the current user, something like:
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
currentInstallation[#"user"] = [PFUser currentUser];
[currentInstallation saveInBackground];
Then, do an installation query like this:
PFQuery *installationQuery = [PFInstallation query];
PFUser *current = [PFUser currentUser];
[installationQuery whereKey:#"user" notEqualTo:current];
Then, continue with your push using this query:
PFPush *push = [[PFPush alloc] init];
[push setQuery:installationQuery]; // <<< Notice query change here
[push setMessage:message];
[push sendPushInBackground];
In theory you send push notifications to all users that are subscribed to some channel ok.
Now you have a table with all users and all channels. Some users are subscribed other are not. First create a query for the installation, than find users that are not current user.
PFQuery *pushQuery = [PFInstallation query];
[pushQuery whereKey:"user" notEqualTo:[PFUser currentUser]];
Create a Push object and use this query.
PFPush *push = [[PFPush alloc] init];
[push setQuery:pushQuery]; // Set our Installation query
[push setMessage:#"Ciao."];
[push sendPushInBackground];
In pushQuery you can use other key, example: deviceID,installationID, deviceType etc..
I use Parse Cloud but i never use push notification so you need to try this code.

How to query/curl for Parse installation without objectId

Say I need to get a particular installation from Parse. I don't have the objectId. How might I query for it? It's concerning iOS push notifications. I already have the deviceId. What is the curl command for that?
If you want to send push to individual user then you need to add some additional info to the installation object for example when the user sign in. So other users can query instalations to find a specific ones. I've done it like this:
PFInstallation *installation = [PFInstallation currentInstallation];
installation[#"client"] = [KZClient currentClient];
installation[#"phone"] = [KZClient currentClient].phoneNumber;
[installation saveInBackground];
And other user can find this installation object by querying like this:
PFUser *friend = [some method to get friend ...];
PFQuery *installationQuery = [PFInstallation query];
[installationQuery whereKey:#"client" equalTo:friend];
PFPush *push = [[PFPush alloc] init];
[push setQuery:installationQuery];
[push setMessage:#"Test message"];
[push sendPushInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
}];

Push Notifications aren't sent - Parse SDK

I'm creating and sending push notifications with Parse SDK, however I'm finding that none of my notifications are arriving. Am I doing something wrong? I've set up the App ID and Provisioning Profile correctly because I can send test notifications from Parse.com Dashboard
// Create new Push Notifications
PFQuery *pushQuery = [PFInstallation query];
[pushQuery whereKey:#"user" equalTo:otherUser];
NSString *pushNotificationMessage = [NSString stringWithFormat:#"%# added you",[[PFUser currentUser] username]];
// Send push notification to query
PFPush *push = [[PFPush alloc] init];
[push setMessage:pushNotificationMessage];
NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:#"added you",#"Alert", nil];
[push setData:dict];
[push setQuery:pushQuery];
[push sendPushInBackground];
Check 'Push Notification' section in your parse after sending push notification from your device.
Check for subscribers,if subscribers are ZERO it means:
Either query is wrong, not returning users.
User's devices are not registered.
For user's creation and device registration you are using custom
class. It is required to register user with built in parse Users
class.
Hope these things will help you. I faced same problems.

How to associate PFUsers to PFInstallations on the fly to send push notifications?

Based on the Parse guide to using Advanced Targeting for push notifications, I understand in order to associate PFInstallations with the current user, one should so in the following manner:
PFInstallation *installation = [PFInstallation currentInstallation];
installation[#"user"] = [PFUser currentUser];
[installation saveInBackground];
My question is, how would be able to do this "on the fly" for other users (i.e. not the current user). For example, I have a Message object that I would like to send to users Sally, Alex and Ben: how would be able to get just the PFInstallations of those users based on their user objectIds, and then set their PFInstallation's so that
//Sally, Alex and Ben's PFInstallations:
[installation setObject:YES forKey:message.objectId];
...so then when I sent out the message, only Sally, Alex and Ben will get the push notification that they received a message from me?
Thanks!
Here was how I managed to do it. Note that recipientIDs are the list of users (user objectIds, to be exact) that I am sending a push notification to.
if (recipientIDs.count > 0){
//Find the users that were just sent the message
PFQuery *userQuery = [PFUser query];
[userQuery whereKey:#"objectId" containedIn:recipientIDs];
//Find the devices associated with these users
PFQuery *pushQuery = [PFInstallation query];
[pushQuery whereKey:#"user" matchesQuery:userQuery];
//Send push to these users
PFPush *push = [[PFPush alloc] init];
NSDictionary *data = [NSDictionary dictionaryWithObjectsAndKeys:
[NSString stringWithFormat:#"New message from %#", [PFUser currentUser].username], #"alert",
#"Increment", #"badge",
nil];
[push setQuery:pushQuery]; // Set our Installation query
[push setData:data];
[push sendPushInBackground];
}
Not sure if this can work - the documentation says
A valid PFInstallation can only be instantiated via [PFInstallation
currentInstallation] because the required identifier fields are
readonly.
https://parse.com/docs/ios/api/Classes/PFInstallation.html

Resources