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?
Related
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"];
My app was working fine. But from last hour it is crashing giving me a log:
Channel name must start with a letter: 2 (Code: 112, Version: 1.7.2)
I am using Parse push notification service and following code to subscribe a channel:
NSString *str =[[NSUserDefaults standardUserDefaults]objectForKey:#"userEmail"]; //asd#lop.com
str = [str stringByReplacingOccurrencesOfString:#"#"
withString:#"-"];
str = [str stringByReplacingOccurrencesOfString:#"."
withString:#"-"];
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation addUniqueObject:str forKey:#"channels"];
currentInstallation[#"user"] = [PFUser currentUser]; //app crashes here
[currentInstallation saveInBackground];
I haven't changed anything. I checked earlier versions of my code and they also crashing at same point. What is the issue i am unable to figure it out.
Your code seems fine and according to what you said that it used to be working I'd think you should try to uninstall/re-install the app on your device and try again.
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.
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.
I have an array of string's that I am trying to save to parse as the channels for push notifications. The array is correct, put I have no idea what is going on. Can anybody throw some light on this? Thanks.
Error:
Error: Bad channel name: TestString123 (Code: 112, Version: 1.1.30)
Code:
- (void)saveSelectedDepartmentsToParse:(NSMutableDictionary *)dictionary {
NSArray *array = [dictionary allKeysForObject:#"YES"];
NSLog(#"Array = %#", array);
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation addObjectsFromArray:array forKey:#"channels"];
[currentInstallation saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error == nil) {
NSLog(#"Parse Save Succeeded");
}
else {
NSLog(#"Parse Save Failed, %#", error.localizedDescription);
}
}];
}
The reason is because Parse does not accept whitespaces or any special characters in the channels. After removing all white spaces and special characters, the operation succeeded.