Is Parse a good alternative to Firebase?

I recently finished re-prototyping a product that used to use Firebase.

The reason I switched was because - no search. Or poor search anyway. Yes, I did use the Firebase Functions to monitor changes for data and yes I did copy ALL the data to Mongo so that I could actually run a capable search ā€¦ but the overhead is TOO HIGH. I shouldnā€™t have to mirror my data and maintain those bridges (and support customers when the triggers fail to fire - yes, it does happen). And the permissions system in Firebase plain sucks IMHO. ACL is much more powerful and IMHO simpler.

So I switched to parse to have an all-in-one - but here are the two main ā€˜gotchyasā€™.

  • Parse can be finiky when working with nested data (setting and getting nested paths), which Firebase is really strong at, so you might might need a mental shift and data restructure here. It seems to want flat SQL like data but Iā€™m a Mongo guy - I like nested data because to me its cleaner and more organized.

  • Data reactivity. Itā€™s non-existant in Parse. If you are used to binding data from Firebase to a Vue or React-type application and having changes magically reflect through your application when the data changes from the view or a central store (eg vuex), itā€™s not going to happen. Getting anything is a get() function which cannot be bound to reactive UI libraries ā€¦ or proxied.

Frankly, with the popularity of Vue and React and such, Iā€™m very surprised that the Parse community hasnā€™t created any reactive view of the underlying data.

In other way, Parse is a dream! Data modelling, relations, ACLs, cloud functions, and serach. Plus it can be self-hosted or commercially hosted from a variety of options (I choose Sashido.io). Its a great option!

That makes me think, how about adding a feature comparison table in the Parse Server README on GitHub?

I am wondering if you are going to provide phone authentication and map services in PS

You can accomplish this with LiveQuery (this has been around for some years, pre 2017 I believe. If I recall correctly LiveQuery was announced around the same time Firebase announced they were using Websockets, which is what LiveQuery uses) which is available in Android, Flutter, JS, iOS, ParseSwift, etc. SDKs. Though I donā€™t know much about Vue, @dblythy and I mentioned this here, seemed similar to SwiftUI from my understanding. From a programming/SDK perspective, you should be able to bind your model (Parse Server Database) to any view. Thereā€™s a simple example of doing this in the Parse-Swift SDK in Swift Playgrounds:

Essentially, in Parse, when your view first comes on screen, you can run a traditional find/first/get query to ā€œpullā€ your data from the server. Then, you can ā€œsubscribeā€ to that query (assuming you have LiveQuery enabled) and bind that to your view to react to any changes on the server.

1 Like

Parse allows nested paths in a few places. Can you let us know where you seen finicky behavior? There is a pending fix for exclude in this PR, but using paths with select and other types of queries should be working well.

Iā€™m not sure what you mean (feel free to explain more), but @moumouls is working on major updates to the Auth adaptors which will allow for 2FA via TOTP and SMS. Keep an eye out!

Hi @cbaker6 - thanks for your reply.

My comment on ā€˜reactivityā€™ isnā€™t related to LiveQuery. Iā€™m aware that LiveQuery (a great feature, btw!) exists and Iā€™m using it. But thatā€™s not what Iā€™m referring to.

When we say reactivity in terms of Vue or React, weā€™re referring to binding the data object to the UI, such that when the data changes, the UI automatically updates to reflect the current state of the object. In Vueā€™s case this involves Vueā€™s internals binding setting setters/getters (Vue 2) or Proxys (Vue 3) which trigger updates to the UI surgically as needed, only where a value has actually changed (so they donā€™t need to re-render the entire component.

The problem - and its a big problem for Parse, IMHO, given the popularity of React and Vue (and friends) - is that the underlying state of the data in Parse Object is only exposed by EITHER a frozen object (object.attributes) or through get(path) - neither of which is or can be made ā€˜reactiveā€™.

I am a part of the other thread you mentioned. The concept is to create a POJO representation of the current state of the Parse object and keep it in sync - either in real-time as sets/gets occur, or per @dblythy on read/save only ā€¦ but itā€™s not so easy to keep the data in sync (firstly) and not so easy to provide a useful representation of the data given relations like Pointers, Relations, ACLs etc. as any of these fields will not be reactive even if the primary object youā€™ve mounted is.

If the Parse community would like to engage in discussion on how to best make reactivity a possibility in Parse, I would happily participate. I personally feel itā€™s a major disadvantage for the platform that limits its usefulness in modern UIs. All the cool kids are using React and Vue (and friends) lately ā€¦ and for a very good reason. They allow us to build powerful applications reliability and quickly. Itā€™s almost a perfect fit for Parse, as the visions are not so different ā€¦ but without first-class reactivity of the data, that value proposition is diminished.

All my own opinions. Please donā€™t roast me :wink:

1 Like

I may understand a little more about Vue now from this comment. Basically, the code I linked in ParseSwift links to a newer way to ā€œsubscribeā€ to a LiveQuery in Swift (not available in the iOS SDK), which takes advantage of SwiftUIā€™s ObservableObject , so it can automatically update views. Are you saying something like this new subscribe in ParseSwift is needed for VueJS? As it stands, the developer currently needs to create this themselves for VueJS and itā€™s either hard or tedious?

Ok wow, what a useful response, thank you!

Ok Iā€™m not a mobile guy so I havenā€™t read the docs for Swift, but your impression sounds correct. Yes, we need an observable object representing the current state of the data in Parse. So that this observable can be bound to a Vue-instance and thus when the data changes (eg I check ā€˜completeā€™ on a task, or change a category), the UI will auto-update.

This is exactly what we need.

Later today I will update an example for you on RunKit so you can see and play with.

I would suggest opening an issue in the JS repo because Iā€™d imagine other people are having this issue too.

Would you mind adding to the VueJS thread what the subclass is missing/what it doesnā€™t do for you? I havenā€™t used it with LQ / nested objects and if they arenā€™t working as expected Iā€™ll make improvements.

Edit: never-mind youā€™ve explained adequately enough in the deep serialization thread.

Issue in JS repo

RunKit example showing Vueā€™s reactivity

@cbaker6

@kulanu In terms of React reactivity, I have worked in this experimental project: GitHub - parse-community/parse-react: [EXPERIMENTAL] React, React Native, and React with SSR (e.g. Next.js) packages to interact with Parse Server backend

Would you mind to share your thoughts on that?

Also, another alternative for what you are looking for is the usage of the GraphQL API via Apollo Client (for example).

From what I can understand from your code and looking at some docs on VueJS, itā€™s based on MVVM, the same as SwiftUI. So I can give my opinions from an MVVM level. It seems from the link that Vue is simply a ViewModel within itself, so Vue is equivalent to the LiveQuery Subscription class in ParseSwift. Because of this, I would think that it would probably be beneficial for the JS SDK to have something similar (tying a Subscription to a generic ViewModel) for LiveQuery as LiveQuery is meant to be reactive by nature. Now if that should be done using VueJS, I have no input there as I honestly donā€™t understand the difference between React, Next, VueJS, xxxJS, as I typically try to stay out the JS land unless itā€™s basic node stuff, Parse-Server, or Cloud Code.

Now tying the Model (Parse Objects) to a ViewModel is tricky (outside of the generic LiveQuery one I mentioned above) from a SDK perspective to me. In my personal opinion, this type of thing should be left to the developer due to the schema being unknown/opaque (essentially) to the SDK (outside of the Parse required keys), every developer will require a different implementation. It sounds like you are saying thereā€™s some limitation with the Parse Object properties in the JS SDK that limit the ability to tie the Model to the ViewModel. From an outsider perspective (me), this seems like it can be worked around with query select, exclude, include, includeAll, and fields (LiveQuery only). What I mean by this is my opinion of how to best leverage Parse in a reactive way is to first find/fetch/first/get the data from the server and then subscribe to the same query using LiveQuery. If you tie the ā€œfind/fetch/first/getā€ and ā€œsubscriptionā€ into one ViewModel your Views should always match the server (assuming you have a good Internet connection of course)

I think some differentiation is needed between being ā€˜liveā€™ - to me this means the data being in sync with the server - and ā€˜reactiveā€™ - that data bindings between the model and view-model being available such that any changes to the data reflect in the UI. LiveQuery to me already supplies the ā€˜liveā€™ part. The issue Iā€™m calling out is the lack of exposure of an data structure within the model (Parse.Object) that allows a developer to easily bind the Parse.Object models data to the UI using a framework of choice. (Vue React, Svelte etc)

I have admittedly limited exposure to it, but first impressions are that I like the currently LiveQuery. Nothing to do there re: this issue.

And I do agree that itā€™s probably up to the developer to implement reactivity ā€¦ but all those popular libraries require the exposure of some type of ā€˜conventionalā€™ structure (POJO like) rather than the frozen obj.attributes and the getters - neither of which can be made reactive.

To me, there are two parts to the solution.

Part 1 - outbound - make the current state of the object be exposed in a non-frozen object
Part 2 - inbound - monitor updates to this object and set the data to state as the data changes through eg form input bindings. And here we have to be careful NOT to use native Proxys which might be the logical way to go because these can also cause issues being bound by libraries like Vue as @dblythy already figured out. (Ode to the never-released Object.Observe :wink:

How to do this within the scope of the Parse.Object Iā€™m not sure. I have started digging through the code but it looks like a bit of a learning curve.

Does the subclass I wrote not work with LQ? As far as I can tell, when LQ receives a new event, fromJSON is called, which then calls _finishFetch. In my subclass I override _finishFetch to build the dot notation representation. So as far as Iā€™ve used it, object.fieldName is always synchronized with object.get('fieldName').

Let me know what problems youā€™re having with my subclass and Iā€™ll continue to improve it :blush:.

The biggest reason why I asked this question at the beginning is my app will be deployed to China and firebase is not available in China. Now, I have installed parse server in China. If you have questions about deploying parse server in China, you can ask me.

It would be interesting to see how to get Push Notifications working for non-Google Play devices.

Usually, you have to use the Push Notifications service provided by another company to solve this problem.

I am thinking about using the Push Notifications service provided by Baidu.

I will let you know after we get this done.

1 Like

Great, I think it would be interesting to add more push adapters for Android devices that are not using Google Play Services, so that Parse Server becomes out-of-the-box compatible with pushes from Huawei, etc. Once you are working on your push solution, maybe there are some learning that we can incorporate into Parse Server and the Parse Android SDK.

Currently, Parse Platform is pretty dependent on Google Play for that matter, and I think it would be good foreseeing to loosen that grip. Not only for apps in China, but also for users anywhere who refuse to use Google Play Services due to privacy concerns.

On my Angular projects, I use {{object.attributes.fieldName}} instead of {{object.get(ā€˜fieldNameā€™)}}. This is reliable enough and facilitates change detection.

Parse documentation officially discourages the direct use of attributes, so I only use it on the HTML views when itā€™s strictly necessary.