Okay, so there is this "Reference" thing that I don't get about Firebase:
const docRef = firestore.collection('users').doc();
You can get a "reference" of a Document but you can't get a reference of a Collection?
Why?
Clearly there can be multiple docs in a collection but there can also be multiple collections in a doc, right? So how is that different?
In Firebase SDKs you will find DocumentReferences and CollectionReferences.
A DocumentReference refers to a document location in a Firestore
database and can be used to write, read, or listen to the location.
The document at the referenced location may or may not exist.
A CollectionReference object can be used for adding documents,
getting document references, and querying for documents.
Note that a CollectionReference can refer to root collections as well as to sub-collections under a Document.
Related
I want to implement a badge system into my Firebase project, but I already have a lot of users. I want to take all the UIDs of my existing users, and create a new corresponding document for them in my new collection, userinfo.
I've searched the docs and I cannot find a way to do this. Can I get some help creating the documents?
If you want to create a new document for each user that already exists in the (users) collection to another (userinfo) collection, then you have to read all documents from the "users" collection and perform a write operation in the "userinfo" collection. But bear in mind to not perform such an operation on the client, but in a trusted environment, such as a server that you control, or using Cloud Functions for Firebase.
I am creating a sample Twitter App in iOS using Firestore. Currently, I have the following root level collections:
users
timelines
In the timelines collection, I have tweets based on the userId and each Tweet also holds a userInfo map, which contains the information about the user who tweeted.
The problem is that if the user updates their name from Steven to Stephan then I can easily update the users collection but I need to go through all the tweets of the user and then update the name. I also need to go through all the replies from that user in other tweets and update the name.
This seems like too much work!
Any ideas how to handle this scenario in Firebase Firestore.
Any ideas how to handle this scenario in Firebase Firestore.
A classical approach to synchronize your different sets of data (i.e. Documents in different Collections) in a denormalized NoSQL Firestore database is to use Cloud Functions.
If the user updates their name from Steven to Stephan
You can trigger a Cloud Function each time a Firestore document is updated or deleted. In this Cloud Function you'll query for the documents to update (i.e. query all the docs in the timelines collection where name === "Steven") and update them (name = "Stephan") with e.g. a batched write.
I wanna try Firebase extension delete user data.
Say in Firestore I have path like this
users/{uid}/inbox/{messageID}
and also
users/{uid}/posts/{postID}
My question is ....
Is Firebase extension delete user data capable to delete all user message documents, and all users posts documents in Firestore ?
from the documentation in here, it seems it can only delete the document that has the same uid in the root main collection only for Firestore. am I right?
From the same documentation you linked:
Configuration Parameters:
...
Cloud Firestore delete mode: (Only applicable if you use the Cloud Firestore paths parameter.) How do you want to delete Cloud Firestore documents? To also delete documents in subcollections, set this parameter to recursive.
When you install the extension, you should see a prompt for this parameter and answer recursive:
- param: FIRESTORE_DELETE_MODE
label: Cloud Firestore delete mode
description: >-
(Only applicable if you use the `Cloud Firestore paths` parameter.) How do
you want to delete Cloud Firestore documents? To also delete documents in
subcollections, set this parameter to `recursive`.
type: select
options:
- label: Recursive
value: recursive
- label: Shallow
value: shallow
default: shallow
required: true
In my firebase app I have
a list of users(all users are registered via Firebase Authentication )
a list of followers for each user
Each user has added a profile photo, the filename of the photo is unique and is saved in a firestore doc called "photoName" document
Only Followers of a user are permitted to read the "photoName" document ( as specified in firestore rules )
I want only the followers to be able to read the profile photo of the user, I have added a rule in cloud storage as follows:
match /profilePhotos/{profilePhotoFile_id} {
allow read: if request.auth.uid != null
}
The cloud storage rules are set on a file-level so is it accurate for me to assume that only the users who are logged in and are also a follower will be able to read the profile photo of another user? Unless they somehow magically guess the unique names of a photo.
Update dated September 28, 2022
Security Rules in Cloud Storage for Firebase now supports cross-service Rules and let you query your projects’ Firestore data, similar to the get() and exists() functions in Firestore Rules.
See this Firebase blog article and this SO answer from Puf.
Previous answer
Is it accurate for me to assume that only the users who are logged in
and are also a follower will be able to read the profile photo of
another user?
No, because it is possible, with the client SDKs to list all the files in a Cloud Storage bucket, as explained in the doc and your Cloud Storage Security Rules allow any authenticated user to read the profile photos files.
Also note that you cannot read Firestore documents when writing Cloud Storage Security Rules.
One possible approach is to use a Cloud Function to generate a signed URL that you store in the Firestore document AND to forbid read access to the profile photos files. Since Cloud Functions use the Admin SDK they can bypass the security rules.
The following Cloud Function code will generate a signed URL each time a file is added to Cloud Storage and save it in a Firestore document. With this signed URL anyone can read the profile photos file.
It's up to you to adapt it to your case by:
If necessary, only treating the profile photos (check that the file name contains profilePhotos)
Saving the URL in the correct Firestore doc: I guess the file name allows linking back to the user document. Also, you will probably have to change from add() to update().
exports.generateFileURL = functions.storage.object().onFinalize(async object => {
try {
const bucket = admin.storage().bucket(object.bucket);
const file = bucket.file(object.name);
const signedURLconfig = { action: 'read', expires: '08-12-2025' };
const signedURLArray = await file.getSignedUrl(signedURLconfig);
const url = signedURLArray[0];
await admin.firestore().collection('...').add({ signedURL: url })
return null;
} catch (error) {
console.log(error);
return null;
}
});
Two additional considerations:
You can use Custom Claims in Cloud Storage Security Rules, but it is not really recommended to use them for your case, see here.
You can also use file metadata in Cloud Storage Security Rules, but again it is not adapted to your case (you are not going to add followers Ids in file metadata each time a new follower registers...)
I'm confused when I read firebase document says that :
Deleting a document does not delete its subcollections!
but this isn't the normal in the firebase console now, I can see when I delete a doc from the console all subcollections that belong to it also gone.
on the other side, the firebase emulator doesn't delete the subcollection and just remove any existing fields on the doc and keep the subcollections in place
I think 🤔 they was referring to giving end user the permission to delete data directly in your app and think it will be a more secure way if they delete data from the app through a Callable function that can be call recursively
Hope this help clearly your doubt