I am making a leaderboard by using firebase realtime database, unity and facebook ( for profile pic and name )
But I am struggling, I am not sure about the way of doing that. I want to display multiple leaderboards -> All time WORLD / REGION / FRIENDS score, monthly WORLD / REGION / FRIENDS and weekly one.
I know I can use cloud functions to reset weekly and monthly leaderboards.
But how can I store world and region scores ?
Now I just have this ->
https://cdn.discordapp.com/attachments/440873502535450627/821361474353889320/ld.JPG
Thanks to that, I can easily get region leaderboards getref.getchild users . getchild france and then orderbyvalue . limittolast ! this is good !
The problem is how could I get world leaderboard ? ( I have other countries ) I am so lost...Do I need to make another structure for my leaderboard ?
There are a number of considerations that you might put into this including pricing, how much you trust the client, &c. Generally, with a NoSQL database like Realtime Database, you might have a lot of redundant data to make up for the fact that your ability to query is limited. It's also really easy to pull in a lot of data by mistake, so you'll see a number of best practices around keeping your database shallow.
With that said, I think I might recommend reorganizing your data a little bit. For example:
Have one node named "users" with all of your users in there. Each "user" in users should be placed in a node that's simply the userid (which makes security rules easier to write), and here you can place the all time score, monthly score, and weekly score. I'd also recommend storing the time you got that score (using ServerValue.Timestamp) so you don't have to worry about going through your users and deleting all the old scores. If your weekly timestamp isn't this week, you know to ignore/overwrite it (obviously, time is hard, so you'll have to work out what a "week" means to players of your game wrt time zones &c).
I'd also put an array of all a user's "friends" under this user node by their user id. That way, when you go to look up friends, you just just ask for "users/" explicitly there.
Now for regional and world leaderboards on monthly and weekly cadences, I'd just copy everything you want to display into that leaderboard node (say username and score) and add the uid if you need to attribute it back to a user (say if you want to click on that score and see their all time record). So if a user lives in France and they get a weekly high score for them, I'd first write that user's "users/" node with the weekly score and timestamp, then I'd go out to the weekly leaderboard for France and add the new score if it qualifies (ie: don't add it if you're only tracking the top 10), then go out to the world leaderboard and add it there.
How you do this copying is up to you. You could make it the client's responsibility with security rules just making sure they're well behaved - which would probably be fast and cheap but might get weird if they go offline partway through updating. You could use a Firebase trigger that would listen for a user updating their node and copy the data out to the respective leaderboards (this would be more expensive since you're paying for Cloud Functions time and a bit slower but will always work once the user node is updated).
A final note is that for, say, weekly leaderboards. I'd have a node that says "this is France's weekly leaderboard right now" and have all clients read that first before figuring out where to write. That way, at a time you decide for when the week turns over, you can change that node and just have people start writing somewhere else. You can then keep the old leaderboard up for some time (ex: maybe you want to see who changed between this week and last), and you can delete it at your leisure after you're sure that all players have their score in (ex: over slow internets, disconnects, &c).
Related
I'm creating a medical booking app in react native I almost done my UI and now I stuck in data structure in firebase. so the way app works is simple: user register/sign in select the doctor or the therapist and that therapist has some dates and times which user should choose from to set an appointment.
so the way I consider to structure my data is the following:
but I need a simpler approach so I can get all my dates as an array and feed my calendar with it (so user could see the available dates)
and also get all the timings for specific day so when a user select a time other users can't select that too.
how can I structure this data in firebase? sorry I'm new to this concepts if you feel this question is dumb and I'm thankful for any help.
if you need any extra information just let me know in comment section.
You might want to consider extractimg meetings to its own collection and using the dates as the id of each document.. So whenever someone wants to book a meeting, you check if there is a document with the ID of the date, and if not, create the meeting
This is my first question ever on SO and I just want you to know that this community have been helping me for quite some time, and I really got this far thanks to all of you. So thank you. 😀
Now, let me tell you a bit about the question:
I have been scratching my head for days trying to figure this database model for a quite complex (for me, at least) appointment app.
Patients choose a day and it's respective hour slot (15 hourly slots - from 7AM to 9PM) to finish booking a appointment with a therapist. The problem is:
I don't want to show unavailable slots so I must do some real-time querying everytime a date is picked.
I found a way to do this by performing a isEqual query to check if the picked date existed on the therapists agenda collection. If false, the date is available.
The thing is: each therapist has their own subcollection called Agenda but I also need to check if the same date is available in a root collection called Appointments, which is also used by other therapists. This Appointments collection is related to the rooms available for booking. There are 3 rooms available and any room can be automatically booked if it's available. It's a quite complex operation so this is driving me nuts.
Root collection
what I got so far
The therapist agenda
I'm pretty sure I lack a few logical skills to solve this and the answer is probably right in front of my face but I'm failing to see it.
Could anyone please shed me a light into solving this puzzle? Is it possible to achieve all of this in one query function (or performing multiple queries in the same function)? Is there a better way or database structure to do this?
Thanks again!
I would suggest that you store the documents with a random ID and store inside of them a new field called appointment_date which will hold the date, after that, you can query the whole appointment collection with a query like whereEqualTo("appointment_date", yourDate), that query will just fetch the appointments of any specialist.
Also you can store an aditional field inside the appointments documents called specialist_id in which will help you also to get all the appointments for each specialist with a query like
FirebaseFirestore.getInstance().collection("appointments").whereEqualTo("appointment_date",your_date).whereEqualTo("speciallist_id",your_speccialist_id)
This is a kotlin code example, but, with this structure you have more flexibility to query for dates in the agenda, and also query for any speciallist dates
Then, you don't need a subcollection inside your specialist called Agenda, you can just do the query above and you can get each specialist appointment
Check: https://firebase.google.com/docs/firestore/query-data/queries
Lets say I wish to track
User action - game he played - which area he stays - his house number.
If I were to track these event actions in Tabular format, it would look like:
UserId|Game|Area|House|Timestamp so on.
Then I can always run SQL queries if I want to answer few business queries. Like
1. In a given day/week, who is the most active User
2. Which game is most-played?
3. Which area plays most events
4. Which user from which area are the most active
Whats the best way to capture this using Google analytics? Will custom dimensions be useful. Or GA is not suitable for this kind of insight?
Thanks.
First of all, the house number is too precise, it would be against GA's ToS.
In GA everything is captured in "hits", you can think of this as one "row" of data.
Let's look at what you wanted to find out:
Most Active User? - This depends on how you determine "Active". Is it the longest Session durations? Tried most games? Most logins? Most sessions? To track a user, you'd need a User ID tracked.
Which game is played the most? - Again, what is played the most? Longest time in game? Most "start" games? This would require you to know the Game that was played and when someone started playing
Which area is most active? -This would go back to the definition of active, the region information is needed along with the active definition
Which users are most active in an area? Same as above, the user would need to be identified and area
To determine which Custom Dimensions (CDs) you want, let's look at the example data points you want to track and try to determine the scope and if it already exists as a standard dimension:
User ID - this is obviously related to the user, makes sense to be user-scoped
Game - This is a tougher CD. I would think that in a single session, users can play multiple games, thus I'd think you'd want this to be hit-scoped.
Area - GA already provides this based on the ISP
Timestamp - GA already provides time dimensions
From above, we can determine that you need to create two CDs, one to track User ID, the other to track the Game.
You can also look into using the userid feature in GA for cross-device tracking.
I built a shopping app using React Native. We have a lot of stores and restaurantes from all over the country registered on our app.
We send messages to our users using FCM when a specific store publishes a new offer, based on user interest and the publisher. If a restaurant posted an offer, we will send to all users registered on the topic "/restaurants". This behavior is bad because maybe the restaurant is too far away from the user, and this offer isn't important to him.
That's why I want to create topics based on a location, so if a restaurant from Chicago posts an offer, I would send just to users registered on "/restaurants/chicago".
Is this the best way to do it? Do firebase offer something similar out-of-box? And how would I keep track of users to know when they go from another city from another?
TL;DR: Text in Bold.
It is possible to create a background service that will (once an hour) get the device location. https://developer.android.com/about/versions/oreo/background-location-limits
Best way to get user GPS location in background in Android
Don't add location background service if you can get away with not having one. It drains the battery.
You should decouple the location from the FCM and use a little bit of prediction. Send a notification when they would start planning to visit the restaurant and resolve their location/group when they open your app.
I assume your app has location permissions enabled. What you should do for your user is store a list of their past locations in the Firebase Database (or the Cloud FireStore). Resolve these locations to a metropolitan area, zipcode, etc. Keep a counter to help weight this location (and to sort)
You should also store a list of restaurants they viewed from a map view...specifically their locations. What you are going to do is compute an approximate distance from a central location and create an average travel time.
E.g. I prefer to eat in a sub metropolitan area that is (on average) 30 minutes from where I live. I also like to eat around 6pm. I need to make a decision about where I want to eat around 5:15pm.
You should also keep track of what times they viewed your app for restaurants in the database To figure out when they start making decisions to eat.
Another concern is the day of the week. For instance, because I live 30 minutes from good places to eat, I will sometimes eat locally. These local places will be packed on certain days of the week.. Thursday they will be packed, Friday will be 1/2 of that, and Saturday is next to nothing. Then Sunday/Monday they pick back up to Friday levels. This is because people are more willing to drive to town on Friday/Saturday night, but they don't want to cook and will eat out on Thursday locally.
Now is when you start using Predictions. Firebase has a Predictions module, and/or you can write Cloud Functions to organize your database and schedule FCM.
First, you need to collect data. One method is to kick off a location service from an hour when they open your app. Hopefully, this will catch your user at which location they chose to eat at (we'll call this the Label, for analytics this will probably be a conversion event). The other trick is to kick off a notification in an hour to rate their dining experience. This doesn't require location background service, and if they open the notification, you can grab their location then.
Having in-App Coupons that the user can present at the restaurant can allow you to grab location.
Also, learn which days of the week they prefer to eat out and which areas they target on those specific days.
If the user is in a different metropolitan area, then waiting until they open the app will allow you to display relevant subscriptions. I flew to Seattle and was starving at 4pm.
Given as many data points (features) as possible (day of week, time of day, day of month, day of 2 weeks, average distance to local restaurants, average distance to metro-restaurants, is_holiday, average_notification_open, average_time_at_restaurant) And data labels (Eat_locally, eat_metro, Eat_home) you should be able to start classifying users into different groups.
So, 1 hour before your user's average eating time, you should perform some server side calculations to determine where your user is likely to eat. For example, if they eat_locally on Thursday night, you should schedule FCM according to the average distance of local restaurants.
Never funnel a specific user to a specific restaurant. Comply with GDPR even if you don't operate in the EU (it covers their citizens). Be transparent with your data collection policy and always try to anonymize/randomize.
I am making an app.. I mean a game type app. it's a quiz app where two people can
pair them up and can answer questions one by one and so on.
what I want is:
I want to make a virtual room,
when USER1 want to play he will click search competitor, a virtual room with random string key will be made with one player.
then when USER2 will click on find competitor button his room will also be created and he will also search all rooms created before him, if any room have less than 2 users then he will join that room and start playing.
I am new so I am not sure if that is good approach but that's all I have planned.
how to count childs of a node (node that we does not know whats its key..
)
see attached image
please find image here
Good start. It's always best to articulate precisely what you want before your start coding. It sounds like you have a pretty good idea of what you want.
I would recommend using Firestore and firebase.auth, even if only anonymous, so that each user can have 'state' and univeral id in their app. In other words when they close and re-open the app, the app keeps a universal id, uid, for them.
If I understand your requirements:
each user can have more than one room
each room has a max of 2 users
Scalability
As far as searching existing rooms, this will not scale without some categorization. What happens if you have 1,000 rooms? How will users search all that? So you would want to add subject matter, or tags, to each room. That way you can query where("tag")==chosenTag.
Basically each virtual room has fields identifying the 2 users (uid's), AND has subcollections - each collection has a document
uid has fields (accountCreateDate, favoriteColor, AND the uid of each room (as a key) they engage in where the value would be an integer where, for example (1== awaiting response, 2==closed, 3==whatever).
Firestore Structure
users(collection > userUid(document containing aboce said)
rooms(collection) roomA(Document w field identifying subject/name) AND sub-collection containing a doc for each pair of participants.