Ive been trying to register username "NataMio" into channels but its being registered under channels like ["global","NataMio"]. but it supposed to be ["NataMio"], anybody faced this issue ? on Android version of my application its registering it as ["NataMio"].
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation addUniqueObject:#"NataMio" forKey:#"channels"];
// [currentInstallation setDeviceTokenFromData:deviceToken];
[currentInstallation saveInBackgroundWithBlock:^(BOOL succeeded, NSError * _Nullable error) {
// code
}];
In your test, seems it contain "global" in default. So you can just set "channels" to ["NataMio"] directly.
Replace the following code:
[currentInstallation addUniqueObject:#"NataMio" forKey:#"channels"];
With:
currentInstallation.channels = #[#"NataMio"];
I'm trying to save multiple channels for the same user
But just keeps me first. Others do not save.
NSString *business =self.business.name;
NSArray *subscribedChannels = [PFInstallation currentInstallation].channels;
for (NSString *channel in subscribedChannels){
NSLog(#"Channel %# ",channel);
}
[currentInstallation addUniqueObject:business forKey:#"channels"];
NSLog(#"Business : %#",business );
[currentInstallation saveInBackground];
When I go to the table of parse web , it is only created the first channel.
What am I doing wrong?
I am trying to get subscriptions added to all PFInstallations for a particular PFUser (for cases of one person using same login on iPhone iPad, etc.). I have a table view of all their Facebook friends who use the app as well. On selecting the friend in row, I want it to get my objectId and query all PFInstallations to get an array of all the PFInstallations where the key usersObjectId matches the PFUser objectId. Then, I can add a value to the channels of each of those PFInstallations. I have:
FriendArray *job = self.jobsArray[indexPath.row];
PFQuery *query = [PFUser query];
//job.facebookid is the Facebook id for that particular user
//each PFUser has a fbId and for those who logged in with Facebook, their Facebook ID is stored here
[query whereKey:#"fbId" equalTo:job.facebookid];
PFUser *user = (PFUser *)[query getFirstObject];
//This gives me the PFUser whose fbId value matches the Facebook id for the row that was selected
NSString *subscription = [#"User_" stringByAppendingString:user.objectId];
PFUser *me = [PFUser currentUser];
PFQuery *pushQuery = [PFInstallation query];
//Trying to get all PFInstallations that match the current user's usersObjectId, so I can add the value to each channel
[pushQuery whereKey:#"usersObjectId" equalTo:[me objectId]];
PFInstallation *allInstallations = (PFInstallation *)[pushQuery findObjects];
[allInstallations addUniqueObject:subscription forKey:#"channels"];
It tells me, though, that PFInstallation cannot be directly queried. How can I do the same thing in cloud code?
Ok, after hours of work, I finally figured it out, and thought would post the solution. If you want to edit all your PFInstallation entries of a certain type (I do this by always putting my PFUser objectId as a new value on PFInstallation), here you go.
For cloud code use:
Parse.Cloud.define("subscribingAll", function(request, response) {
Parse.Cloud.useMasterKey();
var usersObjectId = request.params.usersObjectId;
var newSubscription = request.params.newSubscription;
var pushQuery = new Parse.Query(Parse.Installation);
pushQuery.equalTo("usersObjectId", usersObjectId);
pushQuery.find({
success: function(results) {
response.success(results);
},
error: function() {
response.error("failed");
}
});
});
Then, on your app, you need a PFCloud call to handle all this.
[PFCloud callFunctionInBackground:#"subscribingAll"
withParameters:#{#"usersObjectId": [me objectId], #"newSubscription": subscription}
block:^(NSArray *theCount, NSError *error) {
if (!error) {
int i;
for (i = 0; i < [theCount count]; i++) {
PFInstallation *change = [theCount objectAtIndex:i];
[change addUniqueObject:subscription forKey:#"channels"];
[change saveInBackground];
}
}
}];
The cloud code returns an array where each object is the data from PFInstallation matching the query. You need to run this through a loop, and set each objectAtIndex as a PFInstallation. From there, just do a simple addUniqueObject, and voila, you are done.
In my case, when logging in, it duplicates the objectId to a key called usersObjectId that I made for PFInstallation. So, I login on my iPhone and then again on my iPad, I have 2 different PFInstallations but both with the same usersObjectId. Running all this code allows me to isolate all of my owned Installations and edit them, specifically to go along with the code I use for subscribing to Facebook friends, so that I can be notified when they post something.
It looks like you can only modify a PFInstallation on the current device, and not all from one user or in the cloud.
This is the code shown on parse :
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation addUniqueObject:#"Giants" forKey:#"channels"];
[currentInstallation saveInBackground];
Maybe a workaround could be adding a new default channel that you subscribe every user to that sends them a notification if they should subscribe to a new channel? I'm unsure if this is the best solution, as I do not know in what context you are performing this subscription.
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) {
}];
I'm trying to add / remove channels from PFInstallation but I keep getting the same error message:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Operation is invalid after previous operation.'
My code:
NSString * channel=[NSString stringWithFormat:#"%#%#%#", city, #"_", self.titleLabel.text];
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
if([sender isOn]){
[currentInstallation addUniqueObject:channel forKey:#"channels"];
} else{
[currentInstallation removeObject:channel forKey:#"channels"];
}
[currentInstallation saveInBackground];
There is a bug in addUniqueObject method, when channels is nil.
You should add this before it.
if (currentInstallation.channels == nil)
{
currentInstallation.channels = [[NSArray alloc] init];
}
Also, you should use saveEventually instead of saveInBackGround.
This should be a bug in SDK.