Get a custom key generated when pushing to firebase - firebase

I am saving some data to firebase, I am using golang admin sdk. My problem is when I push object to firebase it generates an ID which is good for some use cases, but I don't need that what need is a custom integer key like 1,3,4.....
The object may look like this after pushing.
I know I can set it by fetching all data then count them and create next id and add my object under that ID but I don't want this. Is there any way to achieve this in firebase automatically.

You can technically do this but it requires some additional setup.
You will have to maintain the current index in a 'global' position and increment it
there is a risk of write failure if there is a race condition between 2 or more users. to minimize this, you can look at using transactions and rules to control the flow of data.
Additionally, you can use cloud functions to process this if you don't want the client to handle the transaction and updating of the global counter.
Sources:
Cloud Functions
Server side increment
Rules for existing vs new data

Related

When writing to Firestore, how can I know that all triggered have finsihed?

Background: I am using Firestore as the main database for my (web) application. I also pre-render the data stored in there, which basically means that I collect all data needed for specific requests so I can later fetch them in a single read access, and I store that pre-rendered data in a separate Firestore collection.
When a user changes some data, I want to know when this background rendering is finished, so I can then show updated data. Until rendering is finished, I want to show a loading indicator ("spinner") so the user knows that what he is currently looking at is outdated data.
Until now, I planned to have the application write the changed data into the database and use a cloud funtion to propagate the changed data to the collection of pre-rendered data. This poses a problem because the writing application only knows when the original write access is finished, but not when the re-rendering is finished, so it doesn't know when to update its views. I can hook into the table of rendered views to get an update when the rendering finished, but that callback won't be notified if nothing visibly changes, so I still do not know when to remove the spinner.
My second idea was to have the renderer function publish to a pubsub topic, but this fails because if the user's requests happens to leave the original data unchanged, the onUpdate/renderer is not called, so nothing gets published on the pubsub and again the client does not know when to remove the spinner.
In both cases, I could theoretically first fetch the data and look if something changed, but I feel that this too easily introduces subtle bugs.
My final idea was to disallow direct writes to the database and have all write actions be performed through cloud functions instead, that is, more like a classical backend. These functions could then run the renderer and only send a response (or publish to a pubsub) when the renderer is finished. But this has two new problems: First, these functions have full write access to the whole database and I'm back to checking the user's permissions manually like in a classical backend, not being able to make use of Firestore's rules for permissions. Second, in this approach the renderer won't get before/after snapshots automatically like it would get for onUpdate, so I'm back to fetching each record before updating so the renderer knows what changed and won't re-render huge parts of the database that were not actually affected at all.
Ideally, what (I think) I need is either
(1) a way to know when a write access to the database has finished including the onUpdate trigger, or
(2) a way to have onUpdate called for a write access that didn't actually change the database (all updated fields were updated to the values they already contained).
Is there any way to do this in Firestore / cloud functions?
You could increment a counter in the rendered documents, in such a way a field always changes even if there is no change for the "meaningful" fields
For that, the best is to use FieldValue.increment.

Best practice for storing global app settings in firestore

I want to know what the best practice is for storing global app settings for your app in firestore. For example if your app has a setting to enable notifications, a setting for what theme color to use, etc. How would you go about structuring your collection and document(s) to make it so you can easily read/write each individual setting.
The method I have tried is creating a Settings Object Model that contains all my apps global settings, then storing and reading the object from Firestore as a single Document - however anytime I want to update a setting I have to retrieve the entire Settings Object from firestore then re-write the entire object back to Firestore after making the change to only a single setting.
The method I have tried is creating a Settings Object Model that contains all my apps global settings, then storing and reading the object from Firestore as a single Document
That's a very convenient way of doing that.
however anytime I want to update a setting I have to retrieve the entire Settings Object from firestore then re-write the entire object back to Firestore after making the change to only a single setting.
There is no need to get the document, in order to make an update. To change the value of a single property, you can simply use call update("propertyName", "newValue") function on your desired document reference.

Use transaction to update value at two different nodes

I have two different nodes in database.
all posts
users
As per the fan-out model when a user adds a post , it gets updated at both all posts and users/uid/posts.
Each post consists of a like button which displays the number of likes.
When a user clicks on it the like should increase by +1.
According to the docs, we use transactionfor this kind of process.
But the problem with using transaction is that it updates only one node as far as i know
But my problem is how shall i update this transaction in both the nodes as mentioned above
Shall i use update method
What is the way to use transaction that gets updated at both the nodes
You can push all your logic for updating the database onto the server side with Cloud Functions for Firebase. Use can use a database trigger to respond to data being written in the database, then execute some JavaScript to make sure the fan-out finishes correctly. It will have the advantage of making sure all the changes happen without depending on the client.
Transactions can't modify data at two different locations at once, but you will still probably want to use them in your client and Cloud Functions to make sure concurrent writes will not have problems.

Firebase Database concurrent data writing

For writing data in Firebase Database I use setValue() in my android app.
My question is: can a value of a variable change, if at the same time I change the value using the Admin API?
All writes to the database from all clients are ordered. It doesn't matter if its from a client app or the admin SDK. If there are two database clients trying to write different values to the same location in the database, the last writer in the order overwrites the previous value, which is then what all the other clients will eventually see.
If you want to decide what to do in the event of a conflict like this, you can use a transaction to make sure that each client gets to know exactly what the prior data was, and what the new data will be. This is how you make things like a counter safe to increment when there are lots of writers trying to increment it.

How to dynamically add index on the server side in firebase?

Lets say I'm making an app with firebase where the user can create permanent lobbies in which they can send permanent dated messages to. The lobby's name is a key in my data structure. What I want to do is that each time a new lobby is created, an index is automatically created on the server side to sort the messages of that lobby by date.
That can probably be done if I have another server listening in to the creation of new lobbies but is there a way to do this without having an additional server? Just through the client? Without compromising the security of the app?
(Note: I'm using the Unity sdk)
There is no way to programmatically add an index, short from updating a rules.json file and uploading it with the Firebase tools/CLI, which I'd highly recommend against.
If you find you need to dynamically add indexes, you've probably structured your data wrong. But without seeing a minimal sample of the JSON (as text, no screenshots please) that reproduces the problem, it is impossible to say more than that.
You can use the Push() function on a database reference. This will create a unique key based on the timestamp so all values can easily be sorted chronologically.
Use Push() anytime you need to generate a new unique key on your database. You can use this for the lobby itself and even the conversations within the lobby.
Source

Resources