I am making a web app using firebase. I was looking into restricting access to certain pages unless there's a subscription. When I looked through the docs all I found was that I could do transactions with stripe and it only applied on signing in and up not restricting pages.
After searching on the internet, I didn't find a viable solution, but three ideas came up to me I could use (which are either with low working possibility or very lackluster to say the least. (all include using stripe.))
One: I would use a middleware to verify the token I get from stripe and then redirect from there. (but all that comes to my mind how I would identify the redirected page in the middleware. And even if that was probable how much time would that take to make it work(if that even is possible), I have no idea.)
Two: in hosting configurations I could call a function when a rewrite is performed. I thought I could call a make a function that verifies the token from the strip when a restricted page is called. (But then again not only is the function accessible after hosting and can be viewed, I don't know if I can call firebase configurations and functions inside the firebase.json.)
third: this is the most viable but has very bad downsides, is authenticating the strip token from in a regular javascript, and if it fails it would restrict the access to the page. Do the same in the rules so that the database section related to that page. (the downside is that the HTML, CSS, and javascript would all be accessible. Only the database functions relating to them are restricted.
So with all that being said, I couldn't find any viable option I could use. So I was wondering if anyone in here have met the same problem and got a solution or do you have any advice I could use.
Note: I am using firebase's realtime database by the way.
If you are trying to restrict access to your webpages/app, you should come up with a logic in your backend or frontend (depending on your app structure) where you could store values needed in Firestore or another solution.
In case you would like to restrict access to Firestore, you can achieve that with Rules.
Let's say I'm developing app like Instagram: for iOS, Android and Web. I decided to use Google Firebase as it really seems to simplify the work.
The features user needs in the app are:
Authorization/Registration
Uploading photos
Searching for other people, following them and see their photos
I come from traditional "own-backend" development where I do need to setup a server, create database and finally write the API to let the frontend retrieve the data from the server. That's the reason why it's unclear to me how it all works in Firebase.
So the question is how can I create such app:
Should I create my own API with cloud functions? Or it's ok to work with the database directly from the client-side?
If I work with the database directly why do I need cloud functions? Should I use them?
Sorry for such silly questions, but it is really hard to get from scratch.
The main difference between Firebase and the traditional setup you describe is that with Firebase, as far as the app developer is concerned, the client has direct access to the database, without the need for an intermediate custom API layer. Firebase provides SDKs in various languages that you would typically use to fetch the data you need / commit data updates.
You also have admin SDKs that you can use server-side, but these are meant for you to run some custom business logic - such as analytics, caching in an external service, for exemple - not for you to implement a data fetching API layer.
This has 2 important consequences:
You must define security rules to control who is allowed to read/write at what paths in your database. These security rules are defined at the project level, and rely on the authenticated user (using Firebase Authentication). Typically, if you store the user profile at the path users/$userId, you would define a rule saying that this node can be written to only if the authenticated user has an id of $userId.
You must structure your data in a way that makes it easily readable - without the need for complex database operations such as JOINs that are not supported by Firebase (you do have some limited querying options tough).
These 2 points allow you to skip the 2 main roles of traditional APIs: validating access and fetching/formatting the data.
Cloud functions allow you to react to data changes. Let's say everytime a new user is created, you want to send him a Welcome email: you could define a cloud function sending this email everytime a new node is appended to the users path. They allow you to run the code you would typically run server-side when writes happen, so they can have a very broad range of use-cases: side-effects (such as sending an email), caching data in an external service, caching data within Firebase for easier reads, analytics, etc..
You don't really need a server, you can access the database directly from the client, as long as your users are authenticated and you have defined reasonable security rules on Firebase.
In your use case you could, for example, use cloud functions to create a thumbnail when someone uploads a photo (Firebase Cloud Functions has ImageMagick included for that), or to denormalize your data so your application is faster, or to generate logs. So, basically you can use them whenever you need to do some server side processing when something changes on your database or storage. But I find cloud functions hard to develop and debug, and there are alternatives such as creating a Node application that subscribes to real time changes in your data and processes it. The downside is that you need to host it outside Firebase.
My answer is definitely NOT complete or professional, but here are the reasons why I choose Cloud Functions
Performance
You mentioned that you're writing an instagram-like mobile device app, then I assume that people can comment on others' pictures, as well as view those comments. How would you like to download comments from database and display them on users' devices? I mean, there could be hundreds, maybe thousands of comments on 1 post, you'll need to paginate your results. Why not let the server do all the hard work, free up users' devices and wait for the results? This doesn't seem like a lot better, but let's face it, if your app is incredibly successful, you'll have millions of users, millions of comments that you need to deal with, server will do those hard jobs way better than a mobile phone.
Security
If your project is small, then it's true that you won't worry about performance, but what about security? If you do everything on client side, you're basically allowing every device to connect to your database, meaning that every device can read from/write into your database. Once a malicious user have found out your database url, all he has to do is to
firebase.database().ref(...).remove();
With 1 line of code, you'll lose all your data. Okay, if you say, then I'll just come up with some good security rules like the one below:
This means that for each post, only the owner of that post can make any changes to it or read from it, other people are forbidden to do anything. It's good, but not realistic. People are supposed to be able to comment on the post, that's modifying the post, this rule will not apply to the situation. But again, if you let everybody read/write, it's not safe again. Then, why not just make .read and .write false, like this:
It's 100% safe, because nobody can do anything about anything in your database. Then, you write an API to do all the operations to your database. API limits the operations that can be done to your database. And you have experience in writing APIs, I'm sure you can do something to make your API strong in terms of security, for example, if a user wants to delete a post that he created, in your deletePost API, you're supposed to authenticate the user first. This way, 'nobody' can cause any damage to your database.
It is unclear whether or not to set security rules for database.
Is it enough to just let in just authenticated users? Do I need more complicated things? I have android app, and do all validations and updates inside app.
The video from IO says that there is possibility that someone can get all your data if he knew your app ID. So if user is authenticated and have app ID and somehow build web app he can get data too? I mean if using simple rules.
I`m asking for risks when building just android app and using simple rules (auth is on).
Is it ok for you if any user could edit/create/delete any data in your Firebase database? If this is not ok, you need security rules (you probably need them)
Firebase's security rules are really powerful and easy to use, I suggest you take a look at the documentation.
You need user id or role specific rules, otherwise somebody for example can easily wipe out your all data, or easily manipulate anything.
I understand the principle and the need for security rules, and I am intending to write them as required.
My questions is in the instance that I forgot/missed to put a rule in for a particular branch in the JSON tree. how will a user/anyone know the paths of my JSON tree to go go malicious adds/removes in the JSON tree?
In my example, I have an iOS app that has the UI, numerous viewControllers, that do all the add/remove of any info/objects to the Firebase backend. How would an end user even know how to manipulate the paths in my Firebase backend when they are not exposed to my Firebase structure?
For iOS apps security isn't as big of a deal, but if someone managed to get a hold of your source code or your firebase's configuration information then they'd be able to set up a dummy project hooked up to your database and be able to manipulate your unsecured branches. For non-iOS apps security is very important as it's pretty straight forward to acquire a firebase's config info.
Explanation of the problem:
Right now my asp.net mvc 3 application is using cookieles="auto" setting which I really hate and I am trying to find something that will allow me to turn that feature off.
So I came across HTML5 storage solutions and I am having some trouble understanding the idea behind it. So basically all I need to do is take my userID variable and move it from one page to another and then on the backend I pull out this userID and pass data to view as a model. Now, how can I do it without cookies and using HTML5 storage? If it's only accessible via JavaScript do I need to pass it via ajax to my controllers? But I don't see any sense in this since I already passed my model to the view with empty userID because the cookie was empty.
Is there a way to access the HTML5 storage in the backend? Maybe I am missing something here, please advise!
No, there's no way except javascript code, which will read storage content and send it to backend. For small portion of data, which should be available to the server, use cookies.
Local storage was created specially for content, which will not be transfered to the server with each request and therefore allowing to store more data, than cookies w/o traffic spoiling.