I'm serching for a solution for a backend and firebase same interesting, but I have some questions before starting to using it.
My question is related to this post (you don't need to read it) Firebase rate limiting in security rules?
The question was how to be sur the client can do the same request more than 1 time every 5 seconds. The anwser is fine. My question is:
If we assume the client app has no bug and it check if there is no more than 1 request every 5 seconds, the only way we can fail the "validate" is if someone is trying to hack (sending request without using the client app). Is there a way to send a callback to a admin user or to write something in the database to tell someone is trying to write faster than expected and the user is maybe a hacker?
Thanks
Security rule failures are not accessible through an API at the moment.
Look firebase is working on a new feature that will allow me to do that
https://firebase.google.com/docs/functions/
"With Cloud Functions database event handling, you can modify the Realtime Database in response to user behavior, keeping the system up to date and clean."
Related
I am trying to implement a notification system for handling notifications similar to friend request notifications. For example, I write the email of the person I want to send a friend request to. then click on send request. I am confused as to after that, what exactly should happen?
Right now I am thinking that on clicking send request, I would create a document in cloud firestore in a 'notifications' collection, which would then invoke a cloud function that sends a push notification to the user with that email. The user now has the option to accept or deny the request. Choosing any of those actions would update the notification document which will again invoke a cloud function that would add both users to each other's friends list and notify the first user.
So my questions are: -
Is this method reasonably good to be implemented in a production app since it is involving many cloud function invocations and document read and writes? Or even better question - How would you implement something like this in a production-grade app?
Is there any other method that is secure (in the sense that no one should be able to wreck this process by changing the code on the frontend) and efficient (less read/writes/invocations)?
Can this be done without creating any document whatsoever? Purely by cloud functions? Then would it be able to capture other user's response to friend request and do the necessary changes?
For the problem you are describing I would approach it in the say way you are doing, and in fact there are not that many operations going on here, since you would have 2 Firestore writes and 2 invocations of cloud functions, not to mention that the second invocation could take a long time to be fired depending on the user's actions, so you don't need to be more efficient than that.
To you final question I would say that it would be difficult to have this implemented without information going through Firestore because you need to store the acceptance of the friend request, and for the same reason mentioned above, you need to store that information somewhere, even if temporarily.
I know I'm late but maybe this will help to someone else.
My way adding sent - receive friend request system is following:
For example:
me:
{
name:'John',
id:'20'
};
stranger:
{
name:'Lucas',
id:'50'
}
When I click add friend (on stranger) I will call function:
addDoc(doc('users', stranger.id, 'receivedFriendRequests'), { user:me });
This function will add ME into his receivedFriendRequests docs so he will be able to get that docs and check users who sent request to him.
So, in notifications Component you have to just get your receivedFriendRequests` docs and map all users and make function to accept friend requests for each of them.
When you click accept you need to delete that user from receivedFriendRequests and store both users in "friends" collection. You can do it in your own way, but I give the best example, in my opinion.
When I request data from Firebase, whatever language or location, I typically send a get request to a node, for instance:
/posts/foo/boo
Is it possible to view somewhere all the logs of the requests sent to Firebase? The reason I am asking is because I am trying to figure out my high costs for Firebase, as I don't see where the requests are made from.
There is no persistent log of such data, but you can use the database profiler to get a log of listens as they are happening.
Also see this recent blog post of someone using the profiler to troubleshoot a performance problem on their database.
I have a server, and multiple clients (web & mobile). When my users log in, I want to start sending them notifications about the content they follow. When they log out, I want to stop sending them notifications.
I've found many Stack Overflow questions that are similar to mine, but none have been completely answered.
The closes to my question was this other question where the accepted answer is to call deleteInstanceId() when the user logs out, which seems like the most solid solution, but in the comments someone copy pasted from the (GCM) docs that "Developers should never unregister the client app as a mechanism for logout or for switching between users". I wasn't able to find the same notice in the new Firebase docs, but I assume that it's the same concept: the InstanceId is not supposed to be user related.
The only alternative I've found, is to send a "signOut" request to my server, with the instanceId, and my server needs to remove the associated instanceId from the user account.
But what if that API call doesn't go through? This seems to be quite a fragile solution.
So this is what I would do now:
Send the instanceId to my server when the user authenticates
Make sure that this same instanceId is not used by another user, since this could happen when the other user logged out on the same device, but the API call didn't go through
When sending notifications, send them directly to the registered instanceIds (initially I had planned on using topics, but in combination with handling my tokens, this seems even more fragile).
When the user logs out, send a signOut request to my API, and remove the instanceId from the user.
Your question seems to just be seeking validation for a design, which really isn't the purpose of Stack Overflow. The Firebase subreddit might be a better alternative for drumming up conversation around the problem.
But I will say that if it works for you, then run with it. Consider also sending the target users's UID in each message, and have your app compare that with the currently signed in user in order to determine if it reached its correct destination. Send a message back to the server if it's not in order to correct the problem.
Firebase Firestore authenticated user write data freely after tampering code, is it possible?
For example, after setting firebase security rule to only allow user write document created by themselves, can hacker tampering the client side code and upVote their own post voteCount from 1 to 1000?
I understand we can set security rule to only allow increment of 1 vote per one write of document. I want to focusing on knowing whether hacker can modified client side code and use the app again as usual. A high confident answer is greatly appreciated. Thank you. I am a happy firebase user
For security purposes, you should assume that the client code has been compromised. After all, it's running on a machine or device that you don't have control over. It's actually pretty easy for someone to change the way JavaScript works in a browser environment.
Firebase has many security and data validation features in its rules system. All security and data verification needs to be done or verified within firebase rules. You can never trust that a client app/web-interface is behaving.
Perhaps votes are stored as a set of user-id: vote, and a user is only allowed to create a slot with their own id, and vote can be 1,-1 for example.
The following quote is taken from Google Developer Blog. https://developers.googleblog.com/2017/08/hamilton-app-takes-stage.html
For example, when someone enters the lottery, the app first writes
data to specific nodes in Realtime Database and the database's
security rules help to ensure that the data is valid. The write
triggers a Cloud Function, which runs business logic and stores its
result to a new node in the Realtime Database. The newly written
result data is then pushed automatically to the app.
I understand that instead of making a request and expecting a request, they followed the following pattern:
Write to real-time database
The write trigger an action
The action triggers some logic and function
The function writes data back to the database
The listener on the app gets a notification about the data written on 4.
App updates UI or takes whatever action.
Hamilton app followed this pattern when someone enters the competition for a ticket. My main concern with the pattern is that if the connection is offline, we won't get results and at the same time we won't get an error. The changes will be updated locally and firebase will update the next time there is a connection, which will make things messy, as the user is expecting a result.
I was wondering if there is an easy way or a pattern to follow, so we will get an error and display it.
The first solution that comes to my mind is to somehow add a time on the save operation. If the save is not done on the live database within x seconds then we display an error. At the same time, we will also need a timeout on the reply. So if we do not get a reply within x seconds we display something to the user.
I hope I am not confused as I did not understand the pattern well. I struggled with the title, so if anyone can improve it, please be my guest.
Even building an offline capable app, if an operations chain relies on a Cloud Function, I'd make it impossible to execute while offline, telling user to retry when he's online.
However this might lead to bad situations as well because you need to check connection every time the user tries to execute the ops, which might be painful.