Removing firebase-generated id of user saved in database - firebase

When I save a user in my firebase db I do it via this path:
/allUsers/serviceUsers/${usersUID}
However, firebase adds another apparent UID to this UID.
Is there anyway to prevent this or tell firebase to not do it?
The first ID after serviceUsers is the ID I care about. The second one is generated by firebase and is making working with these objects in the app more painful. I would like that the user object be directly nested under the ID after serviceUsers. How can I achieve this?

Try to call :
firebase.database().ref("/allUsers/serviceUsers/${uid}").setValue(user)
Instead of :
firebase.database().ref("/allUsers/serviceUsers/${uid}").pus‌​h(user)
The push function generate an automatic id.

Why not just use a regular POST to
/allUsers/serviceUsers/
and return the ID? The path parameter should only be used on an update, read, or delete, if you are adhering to REST.
https://en.wikipedia.org/wiki/Representational_state_transfer#Applied_to_Web_services

Related

Can a Firestore security rule enforce based on a collection name?

So far in developing my app, I've set it up so that users have their own collections for some important things. The catch is that I've named them using their UID.
For example, everyone has a friends list, so for particular user UID123, her friends collection would be called friends_UID123. I'm now trying to set up a security rule to make it so that only an authenticated user where their UID = UID123 can read/modify this collection. How do I set up a rule so that it compares the request's UID to the UID in the collection name?
Update: Based on a comment below, it seems like this might not be possible right now. Maybe in the future though?
I believe it is not possible to match on a partial collection name. You can consider raising feature request as suggested in this thread
You can give a try to workaround mention in the above thread

PageInfo in Firestore not usable

I would like to use pagination in Firestore so I can save a query state and automatically allow users to submit a page token to start a query again. The challenge I am seeing with this is that Firestore does not offer a query token or page token to resume iteration. However, after looking through the docs for GoLang, it looks like there is an exported PageInfo() method that returns a token I am interested in and an unexported fetch method.
Is there a method to use the exported PageInfo() values to allow me to fetch a new set of documents using that existing token?
To use pagination in Firestore Database you can use query cursors with limit() method as mentioned in this document. You can go through this youtube link to know more about it.
You may also consider using pageSize & pageToken query parameters and nextPageToken field with Firestore REST API as mentioned in this document to achieve pagination. There is a similar StackoverFlow thread which may help you.

How to get user email using firebase analytics event parameter?

I'm making app using firebase on back-end part. User can log in myApp using google account and can backup their data.
I want to delete some doc at cloud when user uninstall myApp.
collection ID is user email.
So I need to know user email but I don't know how to get this.
exports.appUninstall = functions.analytics.event("app_remove").onLog((event)=>{
const userEmail = event.user.email;
database.doc(userEmail + "/user_logged_in").delete();
return console.log("Deleted user_logged_in because user uninstalled app");
});
I don't think this is possible with the structure you currently have. As you can see here, the onLog() returns a AnalyticsEvent object that has a UserDimensions object inside of it, however, that object stores the userId and an object with the userProperties.
I can' t say for sure that this userProperties will store the email of your user so you can fetch in firestore, so you need to test this. If not, you will have to find a way get the user document with it's userId, maybe by adding it to the document itself on creation.
This would be easier if you changed the documentId to be the userId instead of the email, if you do that you can simply use the mentioned userId of the event to get the document and delete it.

In Firebase Firestore, is there any way to pass info to the Security Rules which is not part of the path?

I would like to send some info to Firestore database (Firebase), preferably in key-value pairs (but not necessarily), so that it can use it to evaluate access in their rules (both when reading and writing).
However, I don't want this info to be part of the path.
For example, suppose I had some passParameters method:
DocumentReference docRef =
db.collection("cities")
.document("SF")
.passParameters("abc", 123);
Then I could access this info when writing rules, like so:
service cloud.firestore {
match /databases/{database}/documents/cities/SF/ {
allow read, write: if request.parameters.abc == 123;
}
}
Please note, the above is just an example. Real-life uses cases are more complicated. In other words, don't pay too much attention to the example itself, but answer the more generic question: Is there any way to pass info to the Security Rules which is not part of the path?
You can send such parameters using custom tokens. Include those values as claims in the custom token, and use that token in your client when sending request to firestore (or signin).
This link explains how to-
1) create custom tokens, 2) include custom claims in those tokens, and 3) access those claims in the security rules.
You can have a cloud function to generate that custom token with custom claims for a specific user.
If the information you want to pass to firebase as parameter changes frequently, then this is going to be a cloud function call everytime you want to change the parameter value you are passing- so a bit costly. But if parameter tend to change less frequently (like- some role or special privilege that the user have), then this solution should work perfect and that's one of the primary benefits of custom token.
Even though it is not as simple as your example expectation snippet, still this I believe is one way to achieve what you want.
That's not supported. It wouldn't be a very "secure" security rule if the client could just specify whatever security parameters it wants with a query. That's really no different than allowing a client to pass a plaintext password that gives someone access to something. I would expect that sort of information to be discovered by an attacker.

Firebase - Adding properties to authenticated user [duplicate]

I'd like to add a property to a Firebase user object. The user documentation says that I can only store additional properties using the Firebase real time database.
I am unsure on how this can works in practice.
What does the following mean in practice?
You cannot add other properties to the Firebase User object directly;
instead, you can store the additional properties in your Firebase
Realtime Database.
I interpret it as following:
"you cannot modify properties of a FIRUser object but you can combine this with additional objects"
I found the set function documentation which I interpet in this way:
var userRef = ref.child("users");
userRef.set({
newfield: "value"
});
Is this a sensible approach?
You're almost there. In the legacy Firebase documentation, we had a section on storing such additional user data.
The key is to store the additional information under the user's uid:
let newUser = [
"provider": authData.provider,
"displayName": authData.providerData["displayName"] as? NSString as? String
]
// Create a child path with a key set to the uid underneath the "users" node
// This creates a URL path like the following:
// - https://<YOUR-FIREBASE-APP>.firebaseio.com/users/<uid>
ref.childByAppendingPath("users")
.childByAppendingPath(authData.uid).setValue(newUser)
I've added a note that we should add this information in the new documentation too. We just need to find a good spot for it.
According to the Custom Claims documentation,
The Firebase Admin SDK supports defining custom attributes on user accounts. [...] User roles can be defined for the following common cases:
Add an additional identifier on a user. For example, a Firebase user could map to a different UID in another system.
[...] Custom claims payload must not exceed 1000 bytes.
However, do this only for authentication-related user data, not for general profile information, per the Best Practices:
Custom claims are only used to provide access control. They are not designed to store additional data (such as profile and other custom data). While this may seem like a convenient mechanism to do so, it is strongly discouraged as these claims are stored in the ID token and could cause performance issues because all authenticated requests always contain a Firebase ID token corresponding to the signed in user.
Use custom claims to store data for controlling user access only. All other data should be stored separately via the real-time database or other server side storage.

Resources