Firebase database modeling in a appointment app - firebase

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

Related

Advice for templatized timeslots for events in a day

Hello FullCalendar team,
I am looking to build a feature that would limit the type of events that could go into a specific timeslot.
For example, I would like to indicate to a front-desk end-user that only a certain type of appointment was allowed to be entered into the timeslot. Perhaps the timeslot only takes meeting types that are tagged "check-ins" and "follow-ups" arbitrarily set by some higher up admin.
What would be the best way to go about building this limitation and displaying it to the user? I saw that there is an overlap function I might be able to use along with background-events. The higher-up admin might be able to create background-events that if they overlap with another requested event then limits the type. THen it would be very clear that any certain color-coded event set by the higher-admin would indicate that only certain types could be added.
But am I missing a very obvious way to do this? I was hoping there might be an easier way to templatize the day for end-users. Appreciate the advice.

Making a leaderboard with Firebase Realtime database and Unity

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).

Recommended Firebase data structure for my react native app

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

User Deletion API: userDeletionRequests:upsert :: deletionRequestTime field

Can someone give little clarification how to interpret following parameter:
deletionRequestTime: datetime`:
This marks the point in time up to which all user data for the specified end user and Google Analytics property or Firebase project should be deleted.`
If I set it to 1st Jan2018 (GTM), does it delete all user data:
from that date till today (which is how I interpret).. meaning all 2018 data will be gone?
or, (from epoch time) till that date ... meaning all 2016/2017 etc. data is gone and all that remains is 2018 data?
When trying the API > refreshed User Explorer report in GA interface > I notice all-time data seems is gone (giving me impression that this filed is not respected?). But let me wait 72hrs since API request to draw any conclusion..
Thanks for any clarification.
Cheers!
First off i dont think your miss-interperting it I dont think the documentation is clear.
The following is from userDeletionRequest
deletionRequestTime datetime
This marks the point in time up to which all user data for the specified end user and Google Analytics property or Firebase project should be deleted.
Now to me that means that its a point in time that the data should be deleted. as in one day? one minute a time stamp? would this then mean you will need to loop though every hour minute in a day to delete everything.
My current answer is this is confusing. I am going to contact the team for clarification they are in West coast USA we wont get an answer back for several hours. I will updated this when i know more.
Clarification from Google
As per documentation, deletionRequestTime represents a timestamp up to
which all use data will be deleted. In other words, all data from the
beginning of time until the point returned in deletionRequestTime will
be deleted.
I don't believe you can set the deletionRequestTime field. It is set to the time you make the call.
I believe that is why you are seeing this behavior.

Single term answer to Alexa Skill

Background
I'm writing an Alexa Skill and looking to get pieces of information from the user.
The following conversation for example:
Alexa: What month were you born at?
User: April
Alexa: Good. And what was your favorite movie?
User: April
The problem
Given the following utterances:
GetMonthIntent {month}
GetMovieIntent {movie}
Once a user answers April for the second time, the GetMonthIntent might be triggered.
What I have tried
Asking the user to specify which piece of information is giving by using the following utterances:
GetMonthIntent Month {month}
GetMovieIntent Movie {movie}
The question
What is the right way to make Alexa wait for a single term answer based on the current context?
In the same vein as the other answers here, you should take a look at the newest Node.JS library here, which handles state out of the box:
https://github.com/alexa/alexa-skills-kit-sdk-for-nodejs#making-skill-state-management-simpler
You could define:
State_Launch
State_Month
State_Movie
And then return the proper error response if anything other than the GetMovieIntent or GetMonthIntent (etc.) intents are called in the wrong state.
You would have to do data validation on the server side to make sure the "month" is a valid one, and movies are even harder to validate unless you have a list of expected values. That is, if you care to parse them for use beyond repeating back.
Unfortunately, there is no solution. There is no way to specify the 'context' in which a user reply should be interpreted, so you have to tell the user "what was your favorite movie? Please say 'my favorite movie is' and then the name of the movie".
Here are two ASK feature requests that I think would address your issue:
https://forums.developer.amazon.com/content/idea/41062/creating-something-to-help-with-more-structured-qu.html
https://forums.developer.amazon.com/content/idea/55525/allow-a-response-to-specify-a-set-of-expected-inte.html
Personally I think this is fairly important so I voted for those, but they are not near the top.
I ran into this same problem when I created the "Who's on First? Baseball Skit" skill. I handled this by:
Create a sequence number for each response given by Alexa
Write this number to the "session" in the response.
The session is then passed back to your skill by Alexa in the next request.
Read the sequence number from the request to know what the previous question was.
If a given intent could be the answer to multiple questions (eg. month and movie in your case) then use the sequence number to determine which it is.
This should give you ideas on how to deal with repeated answers. The session is quite easy to use. Other options include writing the userId and status to a database like DynamoDB, but I find that the session works in most cases.

Resources