Finding the perfect (Web-)App Stack

Programming - general

2016-04-05 13:41:27

I currently have some projects in my mind and am in the process of finding the best way to create them. As explained in a previous Post I try out different languages and Frameworks for that. Finding the best is really hard since no single service or framework can handle all you need in a simple way.

One of the projects is related to my study plans (I want to study medicine) and organizing all the information about requirements for all the different universities in one place. Right now I have to read through hundreds of wegpages and PDFs to find the required information, which could be written down in about 5-10 lines for every university. So my site should just display all of that information in an organized way with options to filter universities that accept students with certain grades or specific tests they passed so that future students can find their university easier. This will be a pretty simple project, no user authentication, no accounts, just some static information and a couple of forms to filter the data. This could easily be done with PHP and a small database, but also any other Stack. I'm currently leaning towards using Python, the Flask framework and a SQL-Database with Flask-SQLAlchemy, not because this Stack does it better (it's probably the opposite - more complicated than PHP) but because it's an opportunity to learn it with a simple project.

For more ambitous projects I want the best option available though. I develop Colnote right now, which is a collaborative Note app, meaning you can create Notes and Lists of Notes and share them with other people or the public. Of course this is way more complex and has several parts to it, which I'll briefly explain here to help understand the context. There are multiple Apps that will access the server: * AngularJS Webapp * Android Application That leads me to not using a framework like Meteor which seems to be closely coupled to the Webapp. Not good for my mobile applications, of course it is all possible, but too complicated for my preference. So I originally had the following architecture in mind: * Node.js server with Express.js framework and MySQL database * Socket.io to push updates to connected Webapp clients * Google Cloud Messaging (GCM) to push updates to the Android App

This approach got out of hand quickly. As I wanted to implement two important features, image uploading and 3rd party login via Google and Facebook (using Passport), I realized that passport is good for webapps, but is more difficult to work with for native Apps and image upload is something I wanted to do with an external service, either Amazon S3 or Google Cloud Storage (GCS). So I looked for better frameworks and found Loopback which greatly reduces the complexity of writing a REST server. Now I still had to tackle the two problems with images and app signin. Loopback offers extensions for Amazon S3 and passport login, so for the webapp everything would be fine and I'd not have to worry about Socket.io because Loopback has it's own system (change-streams). Still the problems with the native Apps persisted and I still had to write a whole lot of server code, manage my database, keep table definitions up-to-date or implement Loopbacks database migration systems which make it simpler, but not hassle-free. So I went from using my own server and coding my own service to relying on others for that (something I've never done so far!).

Google everywhere

Which "database as a service" is the easiest to use and fits perfectly for a project that requires real-time updates across multiple devices and users? I started reading the Firebase docs more thoroughly (I just checked what they offer about two years ago) and figured they'd be the way to go. Since Google acquired Firebase I can be pretty sure that they will not just quit their service any time soon like Parse does. This eliminates the need for a backend server. I only need my apps with the firebase libraries and since I use Google products throughout (Angular + Android) they are very good and maintained by Firebase themselves. Now I can easily integrate signin across all platforms and have a realtime database connected to all of them. But there still are problems.

Firebase issues

Firebase does not offer file hosting. Well, it does, but only for files I upload, not for files uploaded thorugh the app itself. I could base64-encode my images and store them inline in the database, but that would neither be performant, nor cost-efficient since firebase does not offer lots of storage. It's not made for files. I still have to use another service for that. I'll discuss that later on. The second problem is GCM: Firebase has no option to sync with GCM, so once a user exits the native App, he can't get any notifications or updates about changes of his notes. This is not what I want, so I have to integrate a sync service that handles GCM manually. This means that I have to, again, have my own server running. It keeps a connection to Firebase, watches for Updates, checks which users are affected, retrieves their GCM device IDs and sends a message to them, telling them to sync with firebase to get the latest notes. Although that server is very simple, there is no connection between the apps and it since it only connects to Firebase and GCM, I still have to make sure it runs without errors and does not crash, one more thing to worry about, although nothing too complicated.

Image upload and hosting

So my first idea was to use Filestack to manage image upload, resizing and storing. Filestack is a REST service that takes images, performs transformations and then saves them to a storage service like S3 or GCS. But they don't connect to firebase, meaning I have no control over who can access those images. Now I have to think about whether anyone with the Filestack URL should be able to access those. If I don't want that, I have to again set up my own server that checks permissions in Firebase and depending on that, creates a key that is valid for a limited time to access the image. This is a lot more complicated than the GCM server since users access this server directly, I have to implement authentication, bringing a lot of complexity into the server and going against my idea of not having to handle any of that myself. So another option would be to just host the images without access control, meaning if you guess the filename (probably a hash of the image), you can access it without being logged in. I thought about what the problems that come with that might be. It is not very likely that someone guesses the filenames. Guessing those Hashes would be as hard as guessing password hashes, so the attacker could just hack the entire database instead of only one image. The main problem would be that people could just share image links and anyone will be able to view the images. But anyone can just copy the images from the webapp and share them however they like. So for now I'll probably go with not authenticating image access and using the following system: 1. Image upload to my own server that resizes and stores them somewhere (S3...) 2. The server returns the path to the app which saves it to Firebase 3. Viewing the image works by retrieving the link from Firebase and loading it directly from the storage service

If there is ever a need to make this system more secure, I can do that and implement authentication of image up-/download on my own server via Firebase.

Conclusion

Finding the best service for an app is really hard because no single service offers everything you need. If Firebase could host the files, I'd have my perfect backend, but right now I don't. I really hope they will eventually implement that.