
Open Sourcing Our SDKs - jamesjyu
http://blog.parse.com/announcements/open-sourcing-our-sdks/
======
mmastrac
I really wanted to like Parse, but I saw a startup get burned badly by it
recently. It works great as a fast way to get your app up and running, but it
absolutely falls flat on its face as soon as you do anything more complicated
than a basic read/write interface.

The real problems show up when you've all of a sudden got these old apps out
in the field with no way to upgrade them to a newer version of the DB. If you
aren't being diligent and making all your Parse DB calls through their cloud
functions, you are guaranteed to end up in a situation where your older mobile
clients are holding back schema and feature evolution. You can try to hack
around it using triggers, but these are too buggy to be reliable.

Other examples of where Parse is painful:

\- beforeSave/afterSave triggers are completely unusable! They are
unbelievably limited and each one you add slows your app down by as much time
as it takes to run. If you want to do something like add users to Mailchimp,
you have now tied the length of time it takes to save a user to the length of
time it takes to talk to mailchimp!

\- There is absolutely no way to test your parse code other than uploading it
to a parse app and hitting it. You can hack together some node code that sort-
of tests it, but it's nowhere near representative of what happens on the
server.

\- You can't manage Parse.Config programatically. There's a web interface and
that's that. None of your config can live in your git repo because there's no
way to read or write it from the command-line.

\- The schema tools are pretty bad on the website. IIRC they introduced REST
APIs to make changes to schema recently, but unless you plan on writing
tooling around those, you'll be manually syncing schema between prod/staging
at some point in your life and you'll probably also miss a critical column
that got added.

\- Parse has a bunch of weird datatypes that act strangely in their cloud
code. Want to make a pointer and store it in a parse field? Construct its
internal representation and set it! I wish I was kidding. If you construct a
pointer incorrectly, it can actually create a phantom object in another table.
Also wish I was kidding about this.

\- createdAt and updatedAt are special and Parse won't let you touch them or
set them. Heaven forbid you want to actually set these to a meaningful time
other than the actual last time the record was written. Nope. So you end up
making your own updatedAt columns and just using those.

For your own sanity: stay away from Parse. The range of use cases where it is
actually useful is so narrow that you'll leave that very quickly unless you
are building a toy app.

~~~
roddylindsay
I think one can go pretty far using Parse, and it gives you a lot out of the
box for your mobile clients...but it definitely has its quirks, and you have
to use it in the right way.

1) Don't even bother with their hosted Cloud Code, spin up your own backend
and use the webhooks. As of the JS SDK 1.5 you can finally run a node backend
securely.

2) Push complex logic off the client and into Cloud Functions.

3) Put plenty lot of thought into your schemas before creating them.

That said, there are a few big areas of need that I see that I hope the team
will address:

1) Development/Staging environments are a pain, particularly around schemas.
Tooling around migrations would help a lot here.

2) Testing tools leave a lot to be desired (I had to roll my own backend mock
library for node, [https://github.com/HustleInc/parse-
mockdb](https://github.com/HustleInc/parse-mockdb) )

3) Limited exposure of MongoDB feature set (e.g. aggregation framework)

4) Downtime (and notification speed / transparency thereof)

5) Security/ACLs leave a lot to be desired, particularly for complex schemas.
For instance, it would be great to specify object-level access controls in
terms of Parse queries (e.g. Users that satisfy a query built around the
object in question).

~~~
codegefluester
I'm curious about an example for (5), mind sharing one?

~~~
roddylindsay
Sure. Let's say I have a Group collection, a User collection, and a Post
collection. A Post has a pointer to a Group and is public to that group. I
would like to specify that each Post should be able to be read only by Users
who belong to that group, by having a pointer to that Group in their "group"
field. I could specify this permission at a class level as a Parse Query.

Basically I want a more powerful version of this:
[http://blog.parse.com/learn/secure-your-app-from-the-data-
br...](http://blog.parse.com/learn/secure-your-app-from-the-data-browser-with-
pointer-permissions/)

------
andrewljohnson
Freaking awesome! So much to learn from the code from these guys... plus
easier to use, more trustworthy... and you don't have to wait for the vendor
to fix critical bugs when needed.

I'd really like to see all infrastructure SDKs open sourced (obviously a tough
sell, but maybe Parse paves the way). In building our core stack, we don't
tolerate closed source. But we end up allowing it for things like Crashlytics,
MixPanel, Segment, etc - and it's not a free lunch.

~~~
jamesjyu
Thanks Andrew! Transparency and community involvement is our top priority
here.

Also, we're doing a series of blog posts that will cover each part of the SDK
stack. Lots of learnings to share from our kick ass SDK team.

Here's the first: [http://blog.parse.com/learn/the-parse-sdk-whats-
inside/](http://blog.parse.com/learn/the-parse-sdk-whats-inside/)

~~~
franklinho
YES! It's so important to be able to look under the hood with these things.

When I was working at MoPub, our open source SDK was one of our major selling
points.

------
roddylindsay
What would it take to have these Parse client SDKs support a generic GraphQL
server (and for the Parse backend itself to conform to GraphQL)?

It seems like that would be a promising direction to give Parse apps
flexibility to swap backends down the road, without having to change the
entirety of their client code base...and preserving the out-of-the-box speed
and convenience of using Parse for brand new and prototype apps.

~~~
traviscline
Nothing official but I have a prototype that exposes a parse schema via
GraphQL here:
[https://github.com/tmc/parse_graphql](https://github.com/tmc/parse_graphql)

------
GeneralTspoon
Last time I used Parse the Android SDK had a crippling bug that made it
unusable. This was version 1.8.0 I believe.

Essentially Disk I/O was using the same synchronized lock as the main thread.
On some devices this caused a reproducible ANR (App Not Responding). I ended
up writing a small REST Api client using Retrofit to replace the SDK. It
worked well but as mmastrac mentioned there are just too many other critical
issues with Parse to make it suitable for anything other than quick
prototypes.

Besides, it's super expensive if you need have any sort of scale. You could
almost hire a part-time engineer to build and maintain a backend for those
prices.

~~~
grantland
It's unfortunate to hear you had a bad experience with our SDK :(

We've actually fixed a few ANR deadlocks in this last release [1], as well as
a few others in the releases since 1.8.0 [2].

If you can supply reproduction steps, we'd love to be able to fix this issue
as I'm sure you're not the only one experiencing it. In addition, we're more
than happy to accept fixes as contributions :D

[1]: [https://github.com/ParsePlatform/Parse-SDK-
Android/releases/...](https://github.com/ParsePlatform/Parse-SDK-
Android/releases/tag/1.10.0)

[2]: [https://parse.com/docs/downloads](https://parse.com/docs/downloads)

~~~
GeneralTspoon
The issue is still open here:
[https://developers.facebook.com/bugs/838833329491346/?search...](https://developers.facebook.com/bugs/838833329491346/?search_id)

I think the guy on the ticket didn't really understand what I was saying. I'm
happy to provide any extra info necessary (what I can remember anyway).

From looking through the code, the issue still appears to exist. [1] is called
on the Main Thread. It eventually calls to a synchronized block [2]. [3] is
called from a background thread and uses the same synchronised lock.

\--> Main Thread + Background Thread using same lock == Trouble

One other annoying issue I reported (#937744189590638 - private) was not being
able to update the GCM token. The field is readonly, even though the GCM docs
explicitly state that the key changes over time. Meaning you have to delete
and recreate the Installation - and what happens if you have other objects
linked to that installation? Super annoying. Could be easily solved by making
that field writable.

[1]: [https://github.com/ParsePlatform/Parse-SDK-
Android/blob/mast...](https://github.com/ParsePlatform/Parse-SDK-
Android/blob/master/Parse/src/main/java/com/parse/ConnectivityNotifier.java#L87)

[2]: [https://github.com/ParsePlatform/Parse-SDK-
Android/blob/mast...](https://github.com/ParsePlatform/Parse-SDK-
Android/blob/master/Parse/src/main/java/com/parse/ParseCommandCache.java#L401)

[3]: [https://github.com/ParsePlatform/Parse-SDK-
Android/blob/mast...](https://github.com/ParsePlatform/Parse-SDK-
Android/blob/master/Parse/src/main/java/com/parse/ParseCommandCache.java#L267)

~~~
grantland
I've responded to both your tickets. The deviceType issue seems be resolved
now, but please ping me on Twitter at @grantland if the deadlock issue fails
to re-open. I just need the SDK version you were using since your thread dump
was obfuscated.

WRT the ParseCommandCache links you sent, you're right that there is some
trouble using the same lock on a background thread and UI thread. It would
possibly cause some UI stuttering, but it wouldn't necessarily cause a
deadlock on it's own. There's probably a bit more to it and I'd love to dig
deeper and find out why.

~~~
GeneralTspoon
For any others reading this - can confirm, deviceToken issue is resolved. It
is actually possible to update a pushToken, but you need to have an
installationId set (otherwise you'll get an error saying it's not possible).

Posted more info for the ParseCommandCache ANR in the ticket.

Cheers for taking feedback seriously! :)

~~~
grantland
No problem, thanks for helping us squash this bug!

------
pbreit
Has anyone reverse engineered the server side such that another provider could
step in or you could run it on your own servers?

~~~
dguaraglia
Wouldn't that be more work than just reimplementing whatever CRUD you would
implement in Parse directly?

~~~
gfosco
I wouldn't think so, no. The client SDKs are really powerful and easy to use,
which is what hooks a lot of people on the product. An open-source Parse-
compatible API server would be very interesting (and I've played with the
concept myself.)

------
inglor
The code is surprisingly well documented. For example:
[https://github.com/ParsePlatform/Parse-SDK-
Android/blob/mast...](https://github.com/ParsePlatform/Parse-SDK-
Android/blob/master/Parse/src/main/java/com/parse/TaskQueue.java) looks like
an honest effort to get contributions.

------
sdpurtill
This is awesome. Huge fan of what you guys are doing at Parse!

------
grinich
Why weren't these open sourced from the start?

~~~
csmajorfive
The initial magic of Parse was in the tight coupling of native mobile SDKs
with standard cloud services. We released our first barebones beta SDKs long
before we had a publicly documented (not to mention properly versioned and
stable) server API. So for a while we iterated quickly underneath the hood and
dragged people over to new versions of our cloud APIs with new SDK releases.
It only became feasible to do this after we productized our server side APIs.
And then it took some time to prioritize the project and execute on it.

------
GFK_of_xmaspast
Just the last couple days I tried to get the parse "embedded c" SDK working
(on a non-embedded platform and mixing in with existing c++ code), I found the
"embedded c" docs to be not at all helpful and had to fall back to libcurl and
fumbling out how things worked from the general-purpose API docs.

------
listic
What kind of device is this, displayed on Parse's homepage?
[http://i298.photobucket.com/albums/mm249/hrenistic/parse_wtf...](http://i298.photobucket.com/albums/mm249/hrenistic/parse_wtf_zpssdoi8q6c.png~original)

~~~
gk3
Haha good question! It's nothing specific, but I intended it to look kinda
like a thermostat. When we launched this new homepage animation, we had just
announced our IoT support so the goal of this animation was to convey that
Parse runs on a lot of different things :)

------
sown
As an aside, has anyone else noticed on Android SDK 1.10.0 ParseQueryAdapter
seems to have disappeared?

~~~
immediatedelay
It's been moved to ParseUI-Android: [https://github.com/ParsePlatform/ParseUI-
Android/commit/4fe5...](https://github.com/ParsePlatform/ParseUI-
Android/commit/4fe580e164f0a4059ecb5738cf0903d4f5dadb2c)

~~~
sown
Thank goodness. I thought I was going crazy. Thank you for pointing this out
to me. That jar file is not in the sdk I downloaded.

