Currently I have a user collection with user documents inside and each user has a currentPoints integer field that can get updated from inside the application via a button click
transaction
.update(couponCollectionReference, {
'currentPoints':
FieldValue.increment(10),
});
If someone decided to reverse engineer my app, can they just change the increment to FieldValue.increment(1000) instead, compile the app and just use it like that ?
I am wondering if I should just use cloud functions for the major of these operations
Transactions are designed to protect against race conditions between multiple users, but are not a security mechanism against abuse.
You can catch many forms of abuse in the server-side security rules that you can write for your database. I've written secure voting systems with that, so likely your case can be secured through rules too.
If you search for the [google-cloud-firestore][firebase-security] tag combination, you'll find many questions about the topic.
That said, many developers new to Firebase's security rules are more familiar with securing access through server-side code, which is fine too.
I'm new to react native. I am trying to develop an application that uses firebase user authentication. But there is something I can think of. For example, 2 users have registered to my application but I want to show extra information to the first user according to a condition.
How can I separate these two?
Where exactly should I manage this condition?
The question is not super clear as to what issue you are trying to tackle so I apologize if I am inferring incorrectly.
I use MongoDB personally with a Node/Express backend for user data and haven't used Firebase myself but I'm sure you can do the same things with it. I'll be speaking in Mongo terminology but again I'm sure you can do the same with Firebase and at the least this will give a good idea of the thought process.
I have a UserSchema that holds all the user information. When logged in the client app would get this information to be used on the frontend after authentication.
Assuming you are only displaying "extra" information that doesn't need additional privilege you can just pull in the users data stored in firebase and handle the display of this extra info with logic on your frontend client.
If its extra privilege you need to setup firebase to look at the user data that is authenticating and only serve back information if they have the proper privileges.
Also important to note, you should ensure that when you are updating user information from client -> firebase backend you should ensure that you can only update specific user fields via read/write authentication on firebase.
Hope this gives a little better idea on how this process might look. I'll let someone who has used firebase specifically add tech specifics.
I've developed an app which relies on Firestore for storing some user's data. This app doesn't have any login mechanism, as it uses the device UUID as identifier; we're not managing any sensitive data, btw.
I'm getting daily warnings from Firestore regarding the absence of security rules in my database, but as long as I don't have any login mechanism and my users need to both read and write from it, I can't see any way for implementing a useful security rule.
Is there any pattern I could follow in this situation? Is there any way to create a security rule for allowing to only read and write data created by the same user without any user authentication?
Thanks in advance
It sounds like you want to identify the user, but then without authentication. My guess is that you want to identify them, without requiring them to provide credentials.
If that is the case, you're looking for Firebase's anonymous authentication provider, which assigns a unique, unspoofable ID to each app instance. Signing in anonymously takes very little code, for example for Android it's:
FirebaseAuth.getInstance().signInAnonymously();
After this call completes, the user has an ID that you can then use in your security rules to identify the data from this user.
We're using Custom Claims in Firebase Auth to manage access in Firebase and allow custom UI experience.
We're now working on the User Admin part and we can't find a way to retrieve users by the custom claims.
For example, a user belongs to an organisation and have different access level - admin or user.
We need to allow the organisation's admin to see all their organisation's users.
We'd like to avoid using a separate database to manage organisation users to not double up the data.
Is it possible?
Can we retrieve all Auth users while filtering them by specific Custom Claim?
Thanks!
There is no built-in API to get a list of all users that have a specific claim.
There is an API to get a list of all users in the Admin SDK. So you could use that and then filter the users that have the claim you're looking for.
But performance of this will not be spectacular. So if listing all users with a specific claim is a common use-case for your app, you'll want to reconsider your concern about using an additional place to store the data. Duplicating data to achieve (well performing) use-cases is quite common in NoSQL.
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.