How to dynamically add index on the server side in firebase? - 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

Related

Get a custom key generated when pushing to 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

Change default data collected by Firebase/Google analytics

We use Firebase/Google analytics in our android app. Each event is saved with a lot of extra information (user-id, device-info, timestamps, user-properties, geographical location …). The extra info is there by default but we don’t want it to be collected.
We tried 2 things:
1) Update Big Query Schema
Delete the unwanted columns from Big Query. Unfortunately, Big Query creates a new export every day. So we would need to know where those fields are coming from. Something we don't know.
2) DefaultParameters within the app
Tried to use default parameters from inside the app, so the city will always be null. Here is an example with the user’s city
Bundle defaultValues = new Bundle();
defaultValues.putString("geo.city", null);
FirebaseAnalytics.getInstance(ctx).setDefaultEventParameters(defaultValues);
Unfortunately, we still see geo.city in our BigQuery data filled in.
Is there a way of changing what is collected by default?
There is no way to disable the geography information. Analytics uses IP addresses to derive the geolocation of a visitor. Probably the solution about update Big Query Schema is a viable way. You have to create a system that carries out this update on a daily basis precisely because the export takes place every day.

Fetch new entities only

I thought Datastore's key was ordered by insertion date, but apparently I was wrong. I need to periodically look for new entities in the Datastore, fetch them and process them.
Until now, I would simply store the last fetched key and wrongly query for anything greater than it.
Is there a way of doing so?
Thanks in advance.
Datastore automatically generated keys are generated with uniform distribution, in order to make search more performant. You will not be able to understand which entity where added last using keys.
Instead, you can try couple of different approaches.
Use Pub/Sub and architecture your app so another background task will consume this last added entities. On entities add in DB, you will just publish new Event into Pub/Sub with key id. You event listener (separate routine) will receive it.
Use names and generate you custom names. But, as you want to create sequentially growing names, this will case performance hit on even not big ranges of data. You can find more about this in Best Practices of Google Datastore.
https://cloud.google.com/datastore/docs/best-practices#keys
You can add additional creation time column, and still use automatic keys generation.

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 Meteor Framework partition data?

From what I know it seems that Meteor Framework stores part of data on the client. It's clear how to do it for personal todo list - because it's small and you can just copy everything.
But how it works in case of let's say Q&A site similar to this? The collection of questions are huge, you can't possibly copy it to the client. And you need to have filtering by tags and sorting by date and popularity.
How Meteor Framework handles such case? How it partition data? Does it make sense to use Meteor for such use case?
Have a look at the meteor docs, in particular the publish and subscribe section. Here's a short example:
Imagine your database contains one million posts. But your client only needs something like:
the top 10 posts by popularity
the posts your friends made in the last hour
the posts for the group you are in
In other words, some subset of the larger collection. In order to get to that subset, the client starts a subscription. For example: Meteor.subscribe('popularPosts'). Then on the server, there will be a corresponding publish function like: Meteor.publish('popularPosts', function(){...}.
As the client moves around the app (changes routes), different subscriptions may be started and stopped.
The subset of documents are sent to the client and cached in memory in a mongodb-like store called minimongo. The client can then retrieve the documents as needed in order to render the page.

Resources