2

I got a database of users. Need to implement list which shows only online users. Unfortunately realtime does not filter by key. So it is possible only in Firestore. But Firestore charge for each write/read/update operation so it might be very expensive to use that feature since users are going offline/online all the time and there will be a lot of write/read/update operations. As a solution, I did separate tables in realtime which saves only online users and here I don't need to pay for write/read/update. But at the same time, it is duplicating the database which is also not good practice.

Could you please share your thought on which solution is better from "price" and "clean" point of view. To pay for Firestore and use one db, or use two db but not to pay for each operation?

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
Bo Z
  • 2,359
  • 1
  • 13
  • 31
  • Not clear what you mean when you say FB rtdb can't filter on key and why you can't use it for your whole requirement. Could you show both database structures and maybe that will help clarify your problem. – GrahamD Feb 04 '20 at 18:32
  • @GrahamD cant filter by key means if you have 100 users. each user got key "sex" where 40% female and 60% male. Technically you cant take only female in rtdb. It is possible only in firestore. – Bo Z Feb 04 '20 at 18:35
  • @GrahamD please let me know if you got any question – Bo Z Feb 04 '20 at 19:22

2 Answers2

1

You can perform filtering in FB RTDB, it is not as sophisticated or flexible as Firestore (you can only filter on one key or value at once) but if it is as trivial as your example then it is certainly possible (you need to use indexing to improve performance and limit data download when in production).

On a db structure like this (ignore the nodes below 'root' that are not 'users', I use this 'root' node for multiple code tests during my development):

enter image description here

and using this code (in Flutter/Dart but the same parameters are available in other languages):

    _referenceRoot
    .child("root")
    .child("users")
    .orderByChild("gender")
    .equalTo("male")
    .once()
    .then(
  (DataSnapshot snapshot) {
    print("snapshot.value: ${snapshot.value}");
    if (snapshot.value != null) {
    print("snapshot.key: ${snapshot.key}");
    }
  },
);

I get this output ie.only the male users. Note that in the snapshot the selected users are unordered:

I/flutter ( 4307): snapshot.value: {a2: {hair: brown, gender: male, age: 20}, a3: {hair: brown, gender: male, age: 20}, a4: {hair: brown, gender: male, age: 20}, a6: {hair: brown, gender: male, age: 20}, a8: {hair: brown, gender: male, age: 20}, a9: {hair: brown, gender: male, age: 20}, a0: {hair: brown, gender: male, age: 20}} I/flutter ( 4307): snapshot.key: users

See this for more details of what is possible: https://firebase.google.com/docs/database/rest/retrieve-data

So, to answer your specific question, if the filtering you need to do is trivial, I would use only FB RTDB. If more complex, then will have to be Firestore. You would need to do the math on estimated data storage/download volumes vs. db calls and storage for a view on minimising costs.

GrahamD
  • 2,952
  • 3
  • 15
  • 26
  • Thank you very much for your answer. I found it helpful. But maybe there is some thing like a ZERO point (which can be number of the users in the list lets say 2000) before that point rtdb is better to use. But after that (2000+) it is better to use firestore because maintaining and pricing would be better? – Bo Z Feb 05 '20 at 13:58
  • 1
    That's for you to work out. I recommend Excel what-ifing :-) – GrahamD Feb 05 '20 at 16:52
1

What is better solution for online/offline user feature Firestore or realtime?

It depends on what your requirements are, but you should not consider using one or the other. There is nothing wrong with using both.

Unfortunately realtime does not filter by key.

If you check the docs, there is a section named sorting and filtering data, where you'll find a method named orderByKey():

Order results by child keys.

So actually it is possible to filter the results of a query and order them in the same time.

As a solution I did the separate tables in realtime which saves only online users and here I don't need to pay for write/read/update.

That's a good solution you can go ahead with. Actually, both Cloud Firestore and Firebase Realtime Database work very well together.

But at the same time, it is duplicating the database which is also not good practice.

Oh, it is. This practice is called denormalization and is a common practice when it comes to Firebase. For a better understanding, I recommend you see this video, Denormalization is normal with the Firebase Database and check my answer from the following post:

So you can denormalize the data to obtain queries that are actually not possible or to save some write operation when it comes to Cloud Firestore.

Could you please share your thought on which solution is better from "price" and "clean" point of view. To pay for Firestore and use one db, or use two db but not to pay for each operation?

Use them both.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Thank you very much for your answer. I found it helpful. But maybe there is some thing like a ZERO point (which can be number of the users in the list lets say 2000) before that point rtdb is better to use. But after that (2000+) it is better to use firestore because maintaining and pricing would be better? – Bo Z Feb 05 '20 at 13:58
  • As far as I know, there is no such point. Cloud Firestore and Firebase Realtime Database are two different products that can work together well. A "point" might be when one or the other exceeds your budget. So you might use, one of the other according to your needs. – Alex Mamo Feb 05 '20 at 14:57
  • `orderByKey` unfortunately only sorting but not filtering – Bo Z Feb 05 '20 at 16:25
  • 1
    @BorisRuzanov That's correct but you can use it together with a filter method `yourRef.orderByChild("yourProperty").equalTo("yourValue");`. See, you can order and filter at the same time. – Alex Mamo Feb 05 '20 at 16:30
  • Sure. Let me test little bit and ill write the result and accept it. Thanks a lot for your time – Bo Z Feb 05 '20 at 18:03
  • 1
    I have tested it. It is good to know about that solution but with my structure it wount work because the order field and equal are different. I need to order by `rating` but get only `online_status` fields equal to online. But i am going to mark it as an answer since it suppose to fit basic functionalities – Bo Z Feb 05 '20 at 20:10