Parse.com plugin v2

I’ve tried to set installationId in both the config object and the header, but none of it works. The installationId column in the Session table still remains “undefined” and new sessions are added at each login. As you can see in the debug output from a signup request, installation id gets sent, but it is still somehow ignored.

What am I doing wrong?

Jan 23 04:41:45.597 ********************************************************************
Jan 23 04:41:45.597 ** Parse RESPONSE @ 01-23 15:41:45 [2]
Jan 23 04:41:45.598 ********************************************************************
Jan 23 04:41:45.598 > createdAt: 2016-01-23T15:41:40.247Z
Jan 23 04:41:45.598 > objectId: sWfbjLpo5gE
Jan 23 04:41:45.606 > sessionToken: r:sDFfG5HlP73ASctthRT4aDSvg
Jan 23 04:41:45.607 ********************************************************************
Jan 23 04:41:45.607 ** RESPONSE META
Jan 23 04:41:45.607 bytesEstimated: 110
Jan 23 04:41:45.608 bytesTransferred: 110
Jan 23 04:41:45.608 isError: false
Jan 23 04:41:45.608 responseHeaders:
Jan 23 04:41:45.608    Access-Control-Allow-Methods: *
Jan 23 04:41:45.608    Access-Control-Allow-Origin: *
Jan 23 04:41:45.608    Connection: keep-alive
Jan 23 04:41:45.609    Content-Length: 110
Jan 23 04:41:45.609    Content-Type: application/json; charset=utf-8
Jan 23 04:41:45.609    Date: Sat, 23 Jan 2016 15:41:40 GMT
Jan 23 04:41:45.609    Location: https://api.parse.com/1/users/sWfbjLpo5gE
Jan 23 04:41:45.609    Server: nginx/1.6.0
Jan 23 04:41:45.609    X-Parse-Platform: G1
Jan 23 04:41:45.609    X-Runtime: 0.819689
Jan 23 04:41:45.609 responseType: text
Jan 23 04:41:45.609 status: 201
Jan 23 04:41:45.610 url: https://api.parse.com/1/users
Jan 23 04:41:45.610 ====================================================================
Jan 23 04:41:45.610 ** REQUEST DATA
Jan 23 04:41:45.610 body: {“username”:“x”,“password”:“x”,“email”:“x@x.x”}
Jan 23 04:41:45.610 headers:
Jan 23 04:41:45.610    Accept: application/json
Jan 23 04:41:45.610    Content-Length: 114
Jan 23 04:41:45.610    Content-Type: application/json
Jan 23 04:41:45.610    X-Parse-Application-Id: xxxxxxxxxxxxxxxxxxxxxxxxxxx
Jan 23 04:41:45.610    X-Parse-Installation-Id: 293jdfjc3jdne83ekdle3293kedmde34
Jan 23 04:41:45.610    X-Parse-REST-API-Key: xxxxxxxxxxxxxxxxxxxxxxxxxxx
Jan 23 04:41:45.610 ====================================================================

And below you can see that inspite of storing the sessionToken from the signup and reusing it at a later login, I still get a brand new sessionToken, probably because installationId can’t be set (see my previous post).

Any thoughts?

Jan 23 05:31:09.905 ********************************************************************
Jan 23 05:31:09.942 ** Parse RESPONSE @ 01-23 16:31:09 [3]
Jan 23 05:31:09.944 ********************************************************************
Jan 23 05:31:09.945 > createdAt: 2016-01-23T16:30:37.866Z
Jan 23 05:31:09.947 > email: x@x.com Jan 23 05:31:09.948 > emailVerified: true
Jan 23 05:31:09.948 > objectId: VBjUg45FdA
Jan 23 05:31:09.948 > sessionToken: r:DVNLpiuFR2345esWdfr4DwsQ2
Jan 23 05:31:09.948 > updatedAt: 2016-01-23T16:30:54.632Z
Jan 23 05:31:09.948 > username: x
Jan 23 05:31:09.949 ********************************************************************
Jan 23 05:31:09.949 ** RESPONSE META
Jan 23 05:31:09.949 bytesEstimated: 270
Jan 23 05:31:09.949 bytesTransferred: 270
Jan 23 05:31:09.949 isError: false
Jan 23 05:31:09.949 responseHeaders:
Jan 23 05:31:09.949    Access-Control-Allow-Methods: *
Jan 23 05:31:09.949    Access-Control-Allow-Origin: *
Jan 23 05:31:09.950    Connection: keep-alive
Jan 23 05:31:09.950    Content-Length: 270
Jan 23 05:31:09.950    Content-Type: application/json; charset=utf-8
Jan 23 05:31:09.950    Date: Sat, 23 Jan 2016 16:31:05 GMT
Jan 23 05:31:10.021    Server: nginx/1.6.0
Jan 23 05:31:10.021    X-Parse-Platform: G1
Jan 23 05:31:10.021    X-Runtime: 0.161582
Jan 23 05:31:10.021 responseType: text
Jan 23 05:31:10.022 status: 200
Jan 23 05:31:10.022 url: https://api.parse.com/1/login?username%3dx&password%3dx
Jan 23 05:31:10.022 ====================================================================
Jan 23 05:31:10.022 ** REQUEST DATA
Jan 23 05:31:10.022 body: []
Jan 23 05:31:10.022 headers:
Jan 23 05:31:10.022    Accept: application/json
Jan 23 05:31:10.022    Content-Length: 2
Jan 23 05:31:10.022    Content-Type: application/json
Jan 23 05:31:10.023    X-Parse-Application-Id: xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Jan 23 05:31:10.023    X-Parse-Installation-Id: 293jdfjc3jdne83ekdle3293kedmde34
Jan 23 05:31:10.023    X-Parse-REST-API-Key: xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Jan 23 05:31:10.023    X-Parse-Session-Token: r:DGjYT37InbvE13DGTHBHYeF45
Jan 23 05:31:10.024 ====================================================================
 

Hi,

I would need to see some code to be able to assist further. If you can’t or don’t want to post it publicly, send it to chris at coronalabs and I’ll take a look.

The process I documented was tested numerous times, so I’m interested in your code implementation.

Cheers.

I have sent my code to your email address, thanks!

Hi,

So, after some research (bonking my head on the table) I found out that Parse is expecting a specific type of id. Of course this isn’t mentioned in their docs :blink: . It was working for me due to fact that I was using a hard coded install id that I pulled from another source, which happened to match Parse’s expectations.

Here is a function that will convert to the proper ID format from the device ID. I’m sure it could be fine tuned, but I’ll leave that for the viewer (if anyone comes up with a more compact version, please share).

[lua]

local device_id = system.getInfo(‘deviceID’)

function generateInstallationId( input )
  local crypto = require( “crypto” )
  local hash = crypto.digest( crypto.md5, input )
  local function h( s, e )
    return string.sub(hash, s, e)
  end
  local id = h(1,8)…’-’…h(9,12)…’-’…h(13,16)…’-’…h(17,20)…’-’…h(21,nil)
  return id
end

local install_id = generateInstallationId( device_id )

parse.config:installationId( install_id )

[/lua]

Something to note from the Corona SDK docs is that Windows phone does not provide a device id:

On Windows Phone, this will return “Not Supported Yet”.

If you use this result as a device id, _ you will generate the same installationId for all Windows phone users _. So you’ll need to figure out some other identifier you can use to generate the installation id as shown above.

Additionally, the sessionToken issue has been addressed as well.

Be sure to generate and set the installationId before making any other calls. Hope that does the trick.

Cheers.

Just got a really bad announcement from Parse, they are shutting down the service in one year.

We have a difficult announcement to make. Beginning today we’re winding down the Parse service, and Parse will be fully retired after a year-long period ending on  January 28, 2017. We’re proud that we’ve been able to help so many of you build great mobile apps, but we need to focus our resources elsewhere.

We understand that this won’t be an easy transition, and we’re working hard to make this process as easy as possible. We are committed to maintaining the backend service during the sunset period, and are providing several tools to help migrate applications to other services.

First, we’re releasing a database migration tool that lets you migrate data from your Parse app to any MongoDB database. During this migration, the Parse API will continue to operate as usual based on your new database, so this can happen without downtime. Second, we’re releasing the open source Parse Server, which lets you run most of the Parse API from your own Node.js server. Once you have your data in your own database, Parse Server lets you keep your application running without major changes in the client-side code. For more details, check out our migration guide here.

We know that many of you have come to rely on Parse, and we are striving to make this transition as straightforward as possible. We enjoyed working with each of you, and we have deep admiration for the things you’ve built. Thank you for using Parse.

How ironic… Just as my first tests showed that everything was working fine with develephant’s clarification above.

Well, I guess we just have to start looking for another backend to migrate to…

By the way, thanks develephant! As I said in my previous post, your clarification above did the trick and it all seems to work.

Chris,

As always, I’m extremely grateful for your laboring and sharing such incredible pieces of work that really make it so much easier for developers like myself to create bigger and better projects with richer back-ends.

I’m digging through your new site and API right now.

Thanks!

-Ed

@develephant, this is awesome news. Again, your contribution in helping the community is outstanding. We can’t wait to migrate to it as already we are using your current parse library for 2 projects.

If you need some beta user, don’t hesitate to ask :slight_smile:

Nick

Wow! Mod_parse, coronium, coronium gs, coronium ace, and now this plugin. You da man Chris! I see that this plugin uses the REST API just like mod_parse. Can you tell us what the advantages of the plugin are?

This is awsome news.

I gave the Parse mod a try couple weeks ago and it’s really good. 

What is the main difference between the old version and this new soon-to-be-released version?

Thanks !

Hi,

tl;dr  It’s current, simpler to use, and more full featured. :slight_smile:

Some of the advantages of the new plugin are:

  • Rebuilt code base from the ground up (mod_parse is aging in Internet years).
  • Full access to the Parse API, with a framework to add any new functionality easily.
  • A more ‘query’ like syntax to make it easier to work with the API, including full support for all query operators.
  • It’s a Corona Plugin (not a stand-alone module) so updates and distribution are easier to maintain.
  • Completely documented, with lots of conversion examples from Parse JSON to Lua.
  • Lots of under the hood improvements.

One of the main sticking points most reported with mod_parse is dealing with complicated queries, and how to format those properly. The aim of this plugin is to remove that friction as much as possible with a clearer and simpler syntax, and more in-depth documentation addressing that process.

In addition, the code base will be easier to keep up to date, allowing me to add new Parse functionality as it’s released (as long as it’s included in the REST API of course).

If mod_parse is working for you, you can keep on using it for the simpler use cases, but if you want to get more control over your queries, and access to Parse functionality in general, the plugin will be the way to go. Additionally, mod_parse will not recieve any more updates (except bug fixes) once the plugin releases.

Hope that helps. Thanks for the kind words.

Cheers.

** applause **

Here’s another interesting behavior…

When deleting a User object, the corresponding Session (revocable) object is not deleted automatically for some strange reason. If you delete the session manually first, the user can’t be deleted since you will get an “Invalid sessionToken” error (209). Same thing happens if you try to delete the user first and then the session. If you logout the user, the session is deleted but since User objects can only be modified (in this case deleted) while logged in, the user can’t be deleted like this either. If you try to ignore the zombie session altogether, you will get a 209 error when trying to create another user from the same device.

Is this a “Parse” feature/bug or a “Parse plugin” dito?

Hi,

I certainly won’t miss Parse (just kidding), but that is an interesting situation.

The only documentation I have found in regards to removing Sessions is via logging out the User.

My assumption is this is something you would need to write Parse cloud code to handle (via a Hook). There is a “master-key” that can delete anything without a session involved, but that’s not something you really want in your client code.

I’ll take a look as well to see if anything is obvious.

Cheers.

@develephant: first of all, thanks!

Logging out does indeed remove the session, but since the session is gone, it won’t let me delete the user. The alternative would be to not set the installationId (as described by you in your post January 19 above in this thread) but then the session table would start filling up pretty quick since new sessions would be created e.g. every time the app is restarted instead of existing ones re-used. Personally, I couldn’t care less, but a table with thousands or eventually even millions of rows must affect performance sooner or later.

I’ve read the Parse docs but it does not mention this anywhere, which I find extremely strange…

@develephant: any news on this issue? I’m kind of stuck here… Not being able to delete users is sort of a showstopper when submitting my app to AppStore.

Again, thanks for looking into this, really appreciate it!

Hi,

Just curious, what is the use case for deleting users? Are you allowing users to self-delete? Parse is very specific about not being able to make adjustments on a User account without some type of credentials (this is a common industry practice) or by using the “Master Key” (which you do not want to include in your app, because we are limited to the REST API).

What you are wanting to do may only be possible from Parse Cloud code (as mentioned previously), there is not really much I can do to change how Parse works, unfortunately.

As a side-note, you do know that Parse will not be available as a hosted service come end of year? Are you running your own open source Parse instance?

Cheers.

Hello,

Yes, I wanted to let the users delete themselves. Maybe it’s wrong but it seems user friendly to let the users delete their own account (personally, I don’t like it when I have to contact support to delete an account somewhere).

As long as the user is logged in, the necessary credentials are there, aren’t they? Or maybe deleting should be done by calling a cloud code function and delete the user from there? Then again, what is the use of “parse.User.delete” in the plugin API if Parse functionality does not allow it?

I know that Parse is about to shut down, but I’m following your good advice to stay calm and wait for the landscape of alternatives to become clear (e.g. Corona Cloud). In the mean time, I must make my existing apps work with the current solution, i.e. Parse…