0

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?

user717452
  • 33
  • 14
  • 73
  • 149
  • Do you want help transforming this entire block into Cloud Code or is there an error in it? – hhanesand Feb 18 '15 at 03:28
  • The error told me that I cannot query PFInstallation directly so I know it has to be done on cloud code, just not for sure how. So far I have: `Parse.Cloud.define("subscribingAll", function(request, response) { var usersObjectId = request.params.usersObjectId;   var newSubscription = request.params.newSubscription; var pushQuery = new Parse.Query(Parse.Installation); pushQuery.equalTo("usersObjectId", usersObjectId); });`I'm just not sure how to go from here to use the query and update keys in each of the PFInstallations – user717452 Feb 18 '15 at 03:45
  • hmm, not sure how much I can help you there. Have you taken a look at the [docs](https://www.parse.com/docs/js/) to see if you can find what you need? – hhanesand Feb 18 '15 at 03:53
  • @lightice11 I've looked at them, but don't see where in javascript I can take the Installation files returned and edit them. – user717452 Feb 18 '15 at 03:56
  • From parse docs : `Note that Installation data can only be modified by the client SDKs, the data browser, or the REST API.` – hhanesand Feb 18 '15 at 04:07
  • So I can't query Installation in client sdks, but can only update using it? – user717452 Feb 18 '15 at 04:12

2 Answers2

1

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.

user717452
  • 33
  • 14
  • 73
  • 149
0

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.

hhanesand
  • 990
  • 11
  • 28
  • The idea is this. You have a table view that shows all your Facebook friends who use the app. Clicking one gets their objectId to add to channels. However, I want it to subscribe all devices that user has, so I need to search through all Installations for the current user and update channels on each to accomplish this. – user717452 Feb 18 '15 at 04:15
  • What are you trying to perform by clicking on their name? – hhanesand Feb 18 '15 at 04:17
  • Click their name, match the Facebook id stored in that array path to the key fbId on their PFUser. Retrieve the PFUser objectId, add it to channels on every PFInstallation associated with the current PFUser. – user717452 Feb 18 '15 at 04:24
  • I'm pretty sure there will only ever be one PFInstallation for the current user . Just use `[PFInstallation currentInstallation]` to access + change it. – hhanesand Feb 18 '15 at 04:29
  • There will be multiple. Logon using Facebook on an iPhone, there's 1 PFInstallation. Logon using same Facebook on an iPad, there's another one. – user717452 Feb 18 '15 at 04:37
  • I can get the count of how many there are using PFCloud with parameters and response, and the cloud code of `pushQuery.count().then(function(count) { response.success(count); }, function(error) { response.error(error); });`, I just don't know how to do the actual installation array as a response. – user717452 Feb 18 '15 at 04:37
  • Sorry, I can't help you then. I recommend asking at the [Parse site](https://www.parse.com/questions) – hhanesand Feb 18 '15 at 04:43
  • I've made some success. On cloud code side, I use `pushQuery.find({ success: function(results) { response.success(results); }, error: function() { response.error("failed"); }` this returns the matching PFInstallations that I seek, but it returns it as an NSArray instead of PFInstallation – user717452 Feb 18 '15 at 05:01
  • I finally figured it out. Check out answer I posted if interested. – user717452 Feb 18 '15 at 05:30