0

Context:
I am building a Birthday reminder mobile app with Firebase as the backend. I am considering using scheduled cloud functions to send notifications to the users who have birthdays on that particular day. I am thinking of saving the birthday data in Firestore in 365 separate documents.
eg:
Jan1 - [user1, user2, user3...]
Jan2 - [user4, user5...]
...
Dec31 - [userX, userY, userZ...]

The advantage I am seeing is that the cloud function needs to read only the particular document(the document name can be identified from the current date).
Is this a scalable approach?
Are there any better options to implement this functionality in Firebase/GCP?

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
Adi
  • 361
  • 1
  • 5
  • 23
  • Voted to close for asking an opinion-based question. See https://stackoverflow.com/help/dont-ask for more info. – anothermh Apr 09 '23 at 19:28
  • Disagree. I am not asking for an opinion. I have added a clear problem statement and the home work I have done so far. The scope of my question is not open ended & well narrowed down to the problem I have accurately described. – Adi Apr 10 '23 at 15:13
  • 1
    Asking "Is this a scalable" and "Are there any better options" is really asking for our opinion. The reason is that in NoSQL databases, the structure of your data is driven by the queries you want to run. We don't know what those queries are, right? One angle is having 365 different collections makes performing queries across dates or users challenging. On the other hand if you're not doing that, then, what's the issue? Why would it not be scalable? There are many options - are they better? Perhaps! (... insert opinion here). If you can provide concrete examples, we can probable help more. – Jay Apr 10 '23 at 17:10
  • Let me respectfully disagree sir. I didn't post an open question asking for all possible solutions. If that were the case, I would have agreed with you. But here I have clearly explained a solution I am working towards. And I want to know if there are any cons in it that I am unaware of. How is that asking for an opinion? Regarding "better options", I am genuinely curious to know if there is a better way of doing it. Because I am a student. Isn't that how a student learns? – Adi Apr 10 '23 at 17:42
  • Consider this: Asking a question without us understanding the entire use-case is likely to generate opinions that could be totally wrong. Person 1: It's *not* scalable because queries cannot be performed across collections in that fashion. Person 2: It *is* scalable because there are 365 days in a year and queries will only be run against one day. Asking if it's scaleable is asking for our opinion on your structure without having knowledge of the scope of the project. A con to one developer may not be a con to another. Better for me may not be better for you. Again, it's use case dependent. – Jay Apr 11 '23 at 17:05

1 Answers1

1

I am considering using scheduled cloud functions to send notifications.

That's a very good idea.

I am thinking of saving the birthday data in Firestore in 365 separate documents.

That's also a very good idea, but it will work only as long as the document stays under the maximum limit. According to the official documentation regarding usage and limits:

Maximum size for a document: 1 MiB (1,048,576 bytes)

As you can see, you are limited to 1 MiB total of data in a single document. When we are talking about storing text, you can store pretty much. However, do not store the UIDs as separate fields, it would be better to create a single field of type array in which you can add all UIDs. So you can schedule a Cloud Function each day, read the content of the array and send notifications.

If you think that you can reach 1 MiB, then I recommend you create two documents, one for UIDs that start from a to m and another one for UIDs that start from n to z. If that also doesn't work, create three documents, and so on.

While @MahdiMenacer will work, it is a very costly solution, as you'll have to pay a read operation for each document the query returns. In the solution above, you'll only have to pay for a single document read, or two if it's really necessary.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Hey Adi. Did my answer help? Can I help you with other information? – Alex Mamo Apr 10 '23 at 05:45
  • Hi @Alex. Is adding all UIDs to an array really help? Because as per the explanation here: https://www.youtube.com/watch?v=o7d5Zeic63s, the arrays are supported internally by maps & maps do have an upper limit of 20k fields. With 20k UIDs per document, I will end up creating a lot more documents. – Adi Apr 10 '23 at 15:06
  • Yes, it really helps. Why? Because you'll only have to read a single document rather than paying a read operation for each document that is returned by a query. Besides that, let's say you can add up to 20k UIDs in a single document, so multiply by 365, this is 7.3 million users. That's huge a number. If you create 2 documents, that would be 14.6 million users. If you create for example 10 documents, there will be 73 million users that can have birthdays in a year. I think it is worth paying 10 read operations ($0.000006) for sending 73 million notifications :) – Alex Mamo Apr 10 '23 at 18:04