Android: Using server-side when working with Parse
Asked Answered
H

1

2

Me and my friend are working on an app., and we wish to use Parse.com as our data base from which we can retrieve info. We can't decide what is the best way to access the data on Parse. For the sake of the example, our app. (i.e. client side) needs something stored on the Parse data base (say some number) - should it directly run the query using the Parse API, or should it make a request to a server side, let it retrieve that number from Parse, and send it back to the client?

We know there's no definite answer, but we couldn't find answer regarding this specific situation. We read this post: When to use client-side or server-side?, but this not exactly the same case.

I claim that we should try to seperate as much as possible from client side and data bases, and leave these queries run by someone who's in charge (server), where my friend claims this adds unnecessary complication, since it's very natural to use the tools supplied by Parse to access the data base from the client side, without the need for a protocol etc.

We'd appriciate any advice,

Thank you.

Herminahermine answered 2/6, 2014 at 22:26 Comment(2)
note taken, thank you :)Herminahermine
note that parse is now back4app.com...Sidell
S
10

In general, go right ahead and make a normal call.

I'd encourage you to do that first in any case, to get everything working on both ends.

Then if necessary go to Cloud Code.

If you are going to do more than one platform (ie iOS and Android), cloud code can be a huge timesaver.

BUT don't forget that for simple calls, cloud code is a waste of time. "Normal" Parse calls are amazingly, incredibly, amazingly, fast and quick to work with.

There is absolutely nothing "wrong" with using normal Parse calls - so do that.

Regarding the question, when do you literally have to use a cloud code call -- you'll know, because you won't be able to do it with a normal call :)

Don't forget very often you can simply use "afterSave" or "beforeSave" in cloud code, to do a huge amount of work. You often don't literally need to go to a "custom call" in cloud code.

Here's a fantastic

Rule of thumb for Parse cloud code --------->

If you have to do "more than one thing" ... in that case you will likely have to make it a cloud code function. If you have to do "three or more things" then DEFINITELY make it a cloud code function.

That's a good rule of thumb.

(Again, as I say, often just an "afterSave" or similar works brilliantly...rather than literally writing a full custom call.)

Here's a typical example of a cloud call that saves 18 billion lines of code in all the platforms covered by the dotcom. First the cloud code...

Parse.Cloud.define("clientRequestHandleInvite", function(request, response)
{
// called from the client, to accept an invite from invitorPerson

var thisUserObj = request.user;
var invitorPersonId = request.params.invitorPersonId;
var theMode = request.params.theMode;

// theMode is likely "accept" or "ignore"

console.log( "clientRequestAcceptInvite called....  invitorPersonId " + invitorPersonId + " By user: " + thisUserObj.id );
console.log( "clientRequestAcceptInvite called....  theMode is " + theMode );

if ( invitorPersonId == undefined || invitorPersonId == "" )
  {
  response.error("Problem in clientRequestAcceptInvite, 'invitorPersonId' missing or blank?");
  return;
  }

var query = new Parse.Query(Parse.User);
query.get(
  invitorPersonId,
    {
    success: function(theInvitorPersonObject)
      {
      console.log("clientRequestFriendRemove ... internal I got the userObj ...('no response' mode)");
      
      if ( theMode == "accept" )
        {
        createOneNewHaf( thisUserObj, theInvitorPersonObject );
        createOneNewHaf( theInvitorPersonObject, thisUserObj );
        }
      
      // in both cases "accept" or "ignore", delete the invite in question:
      // and on top of that you have to do it both ways
      
      deleteFromInvites( theInvitorPersonObject, thisUserObj );
      deleteFromInvites( thisUserObj, theInvitorPersonObject );
      
      // (those further functions exist in the cloud code)
      
      // for now we'll just go with the trick of LETTING THOSE RUN
      // so DO NOT this ........... response.success( "removal attempt underway" );
      // it's a huge problem with Parse that (so far, 2014) is poorly handled:
      // READ THIS:
      // parse.com/questions/can-i-use-a-cloud-code-function-within-another-cloud-code-function
      },
    error: function(object,error)
      {
      console.log("clientRequestAcceptInvite ... internal unusual failure: " + error.code + " " + error.message);
      response.error("Problem, internal problem?");
      return;
      }
    }
  );

}
);

If you are new to Parse it's incredibly hard to figure out how to call these from Android or iOS! Here's that one being called from Android ...

this will save you a day of messing about with HashMaps :)

private static void handleInvite( ParseUser invitor, final boolean accepted )
    {
    String invitorId = invitor.getObjectId();
    // you must SEND IDs, NOT PARSEUSER OBJECTS to cloud code. Sucks!

    String cloudKode;
    cloudKode = (accepted? "accept" : "ignore");

    HashMap<String, Object> dict = new HashMap<String, Object>();
    dict.put( "invitorPersonId", invitorId );
    dict.put( "theMode", cloudKode );

    Toast.makeText(State.mainContext, "contacting...", Toast.LENGTH_SHORT).show();

    ParseCloud.callFunctionInBackground(
        "clientRequestHandleInvite",
         dict,
         new FunctionCallback<Object>()
    {
    @Override
    public void done(Object s, ParseException e)
        {
        Toast.makeText(State.mainContext, "blah", Toast.LENGTH_SHORT).show();
        // be careful with handling the exception on return...
        }
    });

    }

And here's the same cloud call from iOS ... well for now, until you have to do it in SWIFT

-(void)tableView:(UITableView *)tableView
        commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
        forRowAtIndexPath:(NSIndexPath *)indexPath
    {
    int thisRow = indexPath.row;
    PFUser *delFriend = [self.theFriends objectAtIndex:thisRow];
    
    NSLog(@"you wish to delete .. %@", [delFriend fullName] );
    
    // note, this cloud call is happily is set and forget
    // there's no return either way. life's like that sometimes
    
    [PFCloud callFunctionInBackground:@"clientRequestFriendRemove"
            withParameters:@{
                            @"removeThisFriendId":delFriend.objectId
                            }
            block:^(NSString *serverResult, NSError *error)
            {
            if (!error)
                {
                NSLog(@"ok, Return (string) %@", serverResult);
                }
            }];
    
    [self back];    // that simple
    }

Note For the iOS/Swift experience, click to: How to make this Parse.com cloud code call? which includes comments from the Parse.com team. Hope it saves someone some typing, cheers

Sidell answered 3/6, 2014 at 8:48 Comment(3)
Amazing! Thank you very much. We're not yet fully familiar with all you wrote, but this gives us a direction. Again, thanks!Herminahermine
@Joe Blow Shall we query directly from the database or use REST API ?? When should we use REST services ?? ( Context : Android App)Hyperbaton
Hi @Prabhu, in short forget REST and use the code example above to go to Parse.Sidell

© 2022 - 2024 — McMap. All rights reserved.