I mainly want to compare using firestore vs mongoDB Stitch queries.
I'm building an app (angular 5 + ios + android). The app is mainly of 2 views profile and feeds.
The profile contains an array of tags(all user post tags) and a timeline of his posts.
every post got its own array of tags and timestamp. so I can filter them.
filters are either AND / OR operation.
In firestore I plan to use object maps so the AND operation can work
In firestore in order to create OR operation, I need to loop on all the possibilities fetch them individually, aggregate the data and remove duplicates. This can be done on the frontend or inside a cloud function.
I also need to run analytics to know the trending tags every day.
If a user got 100s of posts. How will firestore compare to mongoDB Stitch regarding?
Speed
Cost
Related
I have a document in Cloud firestore to which I listen for updates. It has 2 fields, it has a field description and a field for a picture. The picture is approximately 0.2 mb and description is a few words. I wanted to know what would happen if I made changes to the description in the document, I wanted to know if addSnapshotListener actually downloads a fresh new copy of the document or just the field that has been changed.
I indeed see, by looking at how much data is being downloaded in Xcode, a new fresh copy of the document is downloaded.
This is not efficient at all, since the picture field is rarely changed, only the description might change in my application.
Is there a way to optimize this?
Is there a way to optimize this?
Yes! Don't do that.
Firestore (and the realtime database) is not intended to store images or large datasets per field.
You should explore Storage and keep a reference (url) to the item stored in storage in your Firebase.
Cloud Storage is built for app developers who need to store and serve
user-generated content, such as photos or videos.
By leveraging storage if you need to update or change a field in Firestore, you're only working with a small amount of data instead of an entire image worth.
To answer the question; if you read a document from Firebase, it does read the Document and it's child data.
Here's a link to the Storage Docs which shows how to capture a reference to the item uploaded to storage.
https://firebase.google.com/docs/storage/ios/upload-files
If you want to automatically sync the images to all clients and have them available offline, just put them in a separate document.
// Store your small, frequently changing text here:
db.collection('users').doc(userId).set({email: vince#example.com})
// Store your image here:
db.collection('user_profile_pic').doc(userId).set({data: <imagedata>})
I am new to Firestore so I have a Profiles and Users collections. In the Cloud Firestore Console when I click on Database > Firestore > Data tab > Profiles or > Users the console is reading ALL the documents in each collection. These reads are counted in the Usage tab. So my question is if I have lets say 500K documents in the Profiles collection and clicked on Data I will be charged for reading 500K docs just to view the first 25 docs only. Just clicking on Data tab the console reads all the docs of the first Collection.
I tried using the filter but to use it you will have to click on the Collection and read all the docs first then you can edit the filter.
Is this the way it works or is it my misunderstanding?
I faced the same confusion a while ago and upon digging down to the issue I learnt that all the data which gets loaded in the 'Data' tab of Firestore page does count towards the overall Firestore usage.
However, I was concerned with the same question as yours thus I contacted Firebase support. They reverted back confirming the first instinct of mine(Document reads in 'Data' tab does count) BUT initially it reads only the first 300 documents of ANY selected collection, so even if your collection has over 1 million docs, it will still load only the first 300 documents.
They suggested a way around it until the Firebase team finds a legit solution
Bookmarking the Usage tab of the Firestore page. (So you basically 'Skip' the Data Tab and the useless 300 reads)
Adding a dummy collection in a certain way that ensures it is the first collection(alphabetically) which gets loaded by default on the Firestore page.
So my question is if I have lets say 500K documents in the Profiles collection and clicked on Data I will be charged for reading 500K docs
Absolutely not! You are only charged with read operations for the documents that are apart of the query. I don't know the exact number at which the first query is limited but the data is loaded in smaller chunks, with other words a pagination system is implemented. So once you scroll down other elements are loaded and so on.
If you intend to create an app that uses Firestore as backend, please also note that, offline persistence:
For Android and iOS, offline persistence is enabled by default.
For the web, offline persistence is disabled by default. To enable persistence, call the enablePersistence method.
For the web, offline persistence is an experimental feature that is supported only by the Chrome, Safari, and Firefox web browsers. Also, if a user opens multiple browser tabs that point to the same Cloud Firestore database, and offline persistence is enabled, Cloud Firestore will work correctly only in the first tab.
This means, that once you get a document(s) from the Firebase servers, you are not charched anymore since the results are coming from the local cache.
I just have a similar Question like and I find it redundant to post it as a Question so I'm posting it as asnswer,sorry for that,
Question:
this.db.collection(this.collectionName.usersCollection)
.doc(currentUserId).collection(this.collectionName.friendsCollection)
.where("friendID","==",id)
.get().then(snapshot =>{
if(snapshot.empty)
{
this.db.collection(this.collectionName.chatsCollection).add({
user1 : currentUserId,
user2 : id
}).then(docRef =>{
docId = docRef.id;
this.db.collection(this.collectionName.usersCollection)
.doc(currentUserId)
.collection(this.collectionName.friendsCollection).doc(docId)
.set({
friendID: id,
})
this.db.collection(this.collectionName.usersCollection).doc(id)
.collection(this.collectionName.friendsCollection).doc(docId)
.set({
friendID:currentUserId,
})
resolve(docRef.id);
})
}
else{
snapshot.forEach(document =>{
// console.log("friend id",document.data().friendID, " docid: ",document.data().docId);
resolve(document.id);
})
}
})
so here I'm writing and reading the docId ,so will it affect the counts? I cannot have a check properly because with this many other operations are happening.
Thanks .
I was wondering if there was a way to increment a value in Firestore with Ionic. For example, a like button and when clicked a field value 'likes' adds +1 onto the existing value.
I saw examples with 'transactions' where this is done but it was with the Realtime Database rather than the Cloud Firestore. I looked further and could not find any documentation regarding Firestore.
Is there anyway to pull this off without pulling the existing value from the snapshot first?
Thanks,
Troy
There are no server-side increment operators in Firestore. To increase an existing value, your app will first need to read that value.
For an example of using a transaction in Firestore, see updating data with transactions in the Firestore documentation. This literally shows how to add 1 to a field.
In my web app, an authenticated user can pick songs from his spotify playlist to play at a party. I want guests (nonauthenticated users) to be able to view the picked songs on a dynamically created react route and vote on their favorite songs on their own device (probably a phone).
I am using a Mongo, Express, React/Redux, Node stack.
Since the guests don't have access to my app's redux store, the only way they can view the authenticated user's picked songs is through a GET request to my app's database. My initial plan was to just store playlist documents, and the users can GET those playlists to make a request to the spotify api. However, they are unauthorized and need an access token. This means that my database has to store every single one of the songs that the authenticated user picked.
My question has to do with design. I don't think it's a good idea for my one document to hold every song because some people might want to pick thousands of songs, and one document won't be able to hold all of the songs. On the other hand, creating a separate document for each song seems a little bit too excessive.
Can anyone help me figure out which option is better, or if there is a different option I haven't thought of that can avoid this problem altogether? Thank you
Assuming that if you would store each song in a separated document, the main disadvantage of this strategy is the space complexity, you'll need more space to store all documents.
But, supposing you'll keep all song documents at the same collection, it gives some advantages, for example: queries and sorts operations will be more flexible and faster. It helps you to save both processing and development time. A similar logic is showed here.
Use just one document to store all songs makes your database operations more complex, what requires more development time and code to organize all retrieved data on the proper way. Another disadvantage is that it isn't a long term scalable strategy, mainly because the limit of a BSON document is 16MB.
At my vision, the design of separated documents for each song is more appropriate and the reasons are:
Space is monetarily cheap.
Save time complexity must be a priority on all points of software development. Database queries usually are the slower operations in a software. So, reduce the cost of time at database operations is a good objective to seek. Storing all documents in one collection instead of in one document will retrieve all data already organized, with no no need to retreat at code.
I am in the middle of developing an app which harvests tweets, Facebook statuses and Facebook photos for a user. Currently the user sets out exactly when and to they want this harvest to occur and a spider pulls the data during this period. The when and to is stored in a MySQL db and my plan was to store all the tweets, status and photo meta-data in MongoDB (with the actual images on S3).
I was thinking I would just create one collection for each of the periods the user wants to harvest for and then store all the tweets etc from that period in that particular collection.
Does this seem like a reasonable approach?
Does this seem like a reasonable approach?
What the #1 user query? Is it "find activity by period"? If users only ever want to "find by period", then this makes sense.
However, if users want an accumulated view, now you have to gather history for a user and merge it for display.
If you want both a "by this period" and an "accumulated", then I suggest simply stuffing all data into a single user object. It's easy to tag the individual actions with a "harvest run" and a "timestamp".
Mongo Details: MongoDB can handle individual documents up to about 4MB. Most recent versions up this to 8 or 16MB. If you're only using this space for text, please realize that this is a lot of text. A copy of war & peace is just over 3MBs. So you're talking about hundreds of pages of text in 4MB. With 8 or 16MB, you can probably store status updates & tweets for years on most people.
Note that MongoDB has GridFS for storing binary data (like image files), so you'll typically store just pointers to these in the User document.