I am building a one way messaging app using Firebase Firestore, messaging and cloud functions. Messages are sent from a React based web app to mobile devices ('client only'), essentially a cloud pager for a workplace to bulk message staff from multiple sites.
Each message that is sent is saved as a new document in the Firestore database. One of the document fields is { targetSite: 'Site Name Here' }
. A cloud function then sends push notifications to a Cloud Messaging topic with the same name as targetSite
. This essentially sums up the web back end.
The client apps can select from a settings menu what sites they want to subscribe to, then they will receive any notifications targeted at those sites. Due to the limitation of firebase messaging not being able to return a list of devices subscribed to a topic I handle the topic subscriptions by
- Getting a list of sites from the Firestore database and putting them in a topics array
- Unsubscribing the device from all topics in the topics array using
.forEach
- Getting an array that I store locally in
UserDefaults
with the topics the user has chosen to subscribe to. - Subscribe to all the topics in the
UserDefaults
array
This works fine for keeping the devices subscribed to the topics that they need for push notifications.
Where I'm stuck is returning the list of messages from Firestore database to display in the UI. I am aware that Firestore does not currently have an OR
query. My array of subscribed topics could be anywhere from 1 to 30 sites.
If the syntax was valid my query would look something like this:
this.messageListener = db.collection('messages')
.where('targetSite', '==', 'SiteA')
.or('targetSite', '==', 'SiteB')
.or('targetSite', '==', 'SiteC')
.or('targetSite', '==', 'SiteD')
.and('expired', '==', 'false')
.onSnapshot( (snap) => {
Obviously the above syntax isn't valid but it should give some idea of what I'm trying to achieve. What's the best way to dynamically increase or decrease the size of the query and what's the best alternative to not having an OR
statement. Surely there is a better way than simply querying the database 30 times?
Solution
A solution now exists thanks to @Philip for pointing it out. Firebase now supports this functionality albeit with some limitations. See the Firebase Blog
Unfortunately this cannot be marked as an answer due to the thread being flagged as a duplicate and linked to an answer that is now incorrect.