Search code examples
iosparse-platformpfqueryparse-cloud-code

Query PFInstallation and add to channels key from cloud code


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?


Solution

  • 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.