Problem with reading user data of an app developped with Firestore - firebase

I have been introduced to Firebase a few days ago. Since then I have been trying to discover more features and usage of Firebase, in particular, the usage of the Firestore/Realtime Database.
However, as I am reading into more details, I start to think of some questions. I hope someone that is familiar with Firebase can help me answer them
As for User authentication, I understand that I can use Firebase Authentication where I won't see their real password. However, technically, everything that user stores in my Firestore would be visible to me since I am the owner of the Firebase.
For example, if I were to develop a note/chat app, in which the user can access their notes/chat on the iOS app and also Android. That means all their notes data would be saved in my database. If it happens to contain some private data, then I would be able to read it?
Even if I set security rules, that would be only facing client-side, whereas, for me, the owner of the entire firebase data, I could see the whole thing. Surely, as a customer, you won't want to use an app knowing that I can see everything you write
I am not sure if what I said is true or not. If true, is there a possible solution?

Both of your statements are correct. This happens in most of the apps-websites, the admin or some core developers have full access to the data. That's why privacy policy and GDPR exist. You must specify what data you collect and for what reason. If you intend to use your user data for any other reason you must inform them. Be aware that if you disclose any user information without his permission you can be held liable.

Related

How to save user data in db, without logging in?

I am working on a simple app that allows users to search for something using an API and save it to view later.
However, I don't want to integrate authentication in the app. I can, but would rather not as a UX decision. Do you know of a way to generate a device token, that is unique to every device and can be used to store which assets a device has saved in the db?
I am thinking of expo push tokens as a possible solution, but that would require users to accept push notifications - so what happens if a user says no?
Sounds like you could just use react-native-uid to generate a unique id for your device and then store it in AsyncStorage and fetch it from there going forward.
For more inspiration, or perhaps just a more canonical way to do this... read up on suggestions surroundings the recently deprecated constant for installationId here:
https://docs.expo.dev/versions/latest/sdk/constants
I haven't used this before but if you're looking for something bullet proof then this is probably your goal of getting the same concept.
Firebase Anonymous Authentication might be ideal to use in this case. This can be used to create a user in Firebase auth without any credentials and can be useful especially when you are using either of Firebase's databases since you can use security rules with user's UIDs.
However, once the user logs out of the account by any means including but not limited to using sign out option in your app, clearing app data or uninstalling the app, the same account with that UID cannot be recovered. I looked up for AsyncStorage and apparently that gets cleared to if the app is deleted.

Firebase authentication vulnerability. Unknown users in firebase

So I have an app where I have enabled google authentication in my firebase project. 25 people I know were authenticated. When I logged in the backend I saw atleast some 80 entries with some weird sounding email addresses which should not be there. I had to delete all the entries manually, known and unknown ones (didn't needed any after sucessful testing). Now that I want to go live, I am really concerned as to how unknown entires entered my firebase authentication records?
This has recently happened 'again' to another new app/project of mine. This time I disabled that unknown email address and took a screenshot (attached).
I really really need to know and understand how safe is data on firestore. If someone can manage to 'hack' the Authentication part and add thir email to Authenticated list of users they may also be able to penetrate the database somehow in future. Please help me in understanding what is happening?
While researching on this, I could only find this similar question but the answer was just not enough explanation for me.
Unknown user in my firebase user authentication (Flutter/firebase)
firebaser here
Since the configuration data for your project is embedded in the application that you send to your users, any user can take that configuration data and then start calling the API with it. This is not a security risk, as long as you secure access to the data within your project correctly for your requirements.
See Is it safe to expose Firebase apiKey to the public?
What it means to correctly secure access to your data is hard to answer, as it depends completely on your use-case.
For example: the content-owner only access security rules allow a user to enter data in the database, and then they can access the data they entered. With these rules there's no risk if anyone uses the API (and not your app) to do the same. The security rules will ensure they only can access data they're authorized for, no matter what the source is the API calls is.
It may be related to the pre-launch report.
https://support.google.com/googleplay/android-developer/answer/9842757?visit_id=637478112313064713-650300184&rd=1#signin
Step 1: Provide test account credentials if your app has a sign-in screen
If your app has a sign-in screen and you want the crawler to test the sign-in process or the content behind it, you need to provide account credentials. Note: You do not need to provide credentials if your app supports 'Sign in with Google', which enables the crawler to log in automatically.
So I guess it is safe.
The user willwhiteapple#gmail.com is the apple testing when your application is in the process of validation from apple before deploy to TestFlight .

different types of user management on react-native

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.

Flutter: offline local storage syncing with online e.g. firebase

Is this a common/reasonable Use case?
An app allows a user to save favorites locally so that the user doesn't need to signup.
Then the user afterwards desires to share their favorites.
Therefore favorites data needs to be synced from local to remote. The usual local storage for flutter is sqflite, and firebase/store is the remote. However, this seems cumbersome, as sql to nosql conversion is necessary.
I thought that this would be a general issue for UX etc, but I can't find any discussion of this issue? Maybe forcing the user to create an account is the most general solution?
It's a common understanding that if you don't have user account then you can't have any user data associated with your name. You don't have to force the user to have an account or lock them out.
When they favourite something just show a dialog telling them "If you don't have an account your favourites are stored on the device only. If you want your favourites to be available everywhere please create an account" then show options for "Create account" or "No, Thanks"
Create account: Goes to account creation page
No, Thanks: Adds the device to the favourites list and lets the user continue to do what your app does.
There's no problem to solve here from what I'm seeing. If you don't have an account you don't get account functionality. If you track users without them entering anything it's also a little bit illegal and creepy so no need to push the limits on how you can track the same user.
Another way to think of it is to make signup so easy they don't mind and also guarantee that it's worth it. Won't be used for spam or information selling. Take what's app as an example, even though you need to mobile number to send the messages, it's just used as a unique identifier and has nothing to do with the device's number.
Ask for their phone number or email or just any email, you'll most likely get fake info.
And what does your analytics say? Are you getting requests from users saying they lost all their information on a different device? How many people are using your favourite functionality?
I may have come to the party a little late here but here's my 2 cents worth.
The Sql to NoSql conversion is not cumbersome. In fact, there is a reasonable use case for this. I have the same requirement for an app that I am about to build.
Anyway, to store data in RDMDB or NoSQLDB you will need a data model to ensure consistency in your app. If the user has been using the app offline, and they later choose to go online, you can allow them to create the Remote Account, then check if they have local favorites. If they do, you will HAVE to ask them if they'd like to import them into the remote storage. If they choose to do so, you will then have to read their favorites from the local storage and store them in a List<Model> then map() that back to the online storage.
NoSqlDB can accept the json type data, so your model should include the conversion fromMap() and toJson() for this purpose (and others).
When I have come around to doing this, I will share my code (if I remember to come back here).

Understanding the Firebase and purpose of google cloud functions

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.

Resources