React Native game, MongoDB or Firestore - mongodb

I am working on a multiplayer react native game for android, it's just a text game.
For now, I've been working only on the client side but I'm slowly getting to the point where I need to choose a way to manage data. Since I'm always trying to learn something new - first time using RN too -, I came across Firestore and I'm curious if it's a viable choice from my project.
For example, in this game you can buy/open companies. If I were to handle this action in nodejs + MongoDB I'd send a JWT token to server/api/newcompany.
Assuming I'd have 2 MongoDB models, Users with all the user info and Company a list of all Companies in game. First I'd check if the User had enough money to open the company and then return some message based on that, my code would be something like this:
// routes.js
...
router.post('/api/newcompany',AuthCheck, Company.new)
// controllers/company.js
...
new: async function (req, res, next) {
if (!req.body.companyType || !validCompanyType) {
return res.status(200).send('invalid/missing message and other failed checks')
}
//assuming token data would be passed from auth middleware and would have company prices somewhere
const user = await Users.find({id:token.userId})
if (user.money < companyPrice) {
res.status(200).send('no money')
} else {
const newCompany = new Company()
newCompany.name = req.body.name
...
new.Companny.save(function(){
res.status(200).send('all good')
})
}
}
Looking at Firestore I'd have the same 2 documents as above. Users with a list of sub-documents(the users) identified by their IDs and a document Companies.
Would I be able to do the same users checks as above?
How would I handle that? Would I use the Firestore Rules to check the user has enough money or would I use my server with admin SDK as an intermediary to handle more complex ops and use the direct Firestore connection just for retrieving data?
Thanks for your time.

Related

How can I retrieve all row of one column in firebase flutter

I am trying to make a firebase database call to retrieve all row of one particular column in the firebase database of my app and display it in a textbox in my flutter app.
That is, to retrieve all phone numbers in the Users table.
For instance, in SQL we can do like this:
SELECT (PhoneNumers) FROM Users
I am new in flutter/dart, I need some help.
Its really easy.
First of all, setup and initialize firebase in you project. Then make a function and create an instance of firestore like this
FirebaseFirestore firestore = FirebaseFirestore.instance;
Then make something called Collection reference:
CollectionReference users = await firestore.collection("users").get().then((querySnapshot) {
querySnapshot.docs.forEach((doc) {
print(doc["PhoneNumber"].toString())
});
This will grab every collection from Users, loop over them and then print out the document PhoneNumber to console. There is no way to just get a single document field from firestore. It might seem weird, but its quite useful at times. Right now, you have access to every document field of every user of your app.

How to design model for storing day wise timings?

I am designing a schema for doctor's appointments. The doctor will be given the option to update his/her timings for individual days of the month. Also there is no limit to months. For instance, the doctors will be able to update the timings for any days of future or current month. (Only previous dates will be disabled). The front end part has been done but what I fail to understand is how to create the mongo model for it. Of course I can not have dates for all months stored in the model. What is the method to address this problem? TIA
If it was me that had such project, I would start with 5 collections:
one for users (so you know who did what)
one for patients (recording all about the patient, including mobile number)
one for doctors (so you can show a list while registering time)
one for time registrations (with all details of the registration)
one for logging everything a user does
so you can go back in time and to know how did what... it's never to point the finger to the person that made the mistake but look at it as a very easy way to find out what it happened and how can you prevent it from happening again.
the content of each document is entirely up to you as that will change with exactly what and how you are doing
I would think about something between these lines:
// Users
{
username, hashedPassword, // credentials
permissions: [], // for when you start using permissions
active, // never delete data, just set the flag to "false", if, by GDPR rules you need to delete, you can change the name to "DELETED BY GDPR" and still maintain all references
}
// Patients
{
name,
address: { street, street2, city, zipcode, country }, // for invoicing proposes
mobile, // so you send them an SMS 24h before saying their appointment is "tomorrow"
}
// Doctors
{
name,
weekAvailability: [], // days of the week that a doctor is available as they normally work in more than one clinique
active, // never delete data, just set the flag to "false", if, by GDPR rules you need to delete, you can change the name to "DELETED BY GDPR" and still maintain all references
}
// Logs
{
action, // for example, "save", "add", "change"...
entity, // the collection name that the change happened
originalEntry, // the full document before changes
newEntry, // the full document after changes
timestamp, // the exact time of the change
user, // ref to users
}
// TimeRegistrations
{
user, // ref to users
patient, // ref to patients
doctor, // ref to doctors
title, description, appointmentStart, durationInMinutes,
}
regarding the infrastructure ... create an API (REST or GRAPHQL, the one you're most comfortable with) so you can separate the business logic from the frontend right from the start
your frontend (maybe React, Angular, VueJs) should call a proxy (nodeJs server running aside the frontend) to make authentications and call the API so all you should do in the frontend to be something like
fetch('/api/doctors')
.then(res => res.toJson())
.then(json => {
this.doctorsList = json
})
same as for authentication os a user where you can easily make use of a library to provide you with a JWT and easily maintain user logged in and with the right set of permissions
First approach but not good in your case i.e. One collection,
//doctors
{
_id: "",
appointments: [] // all appointments there
}
Second will be better but note in NoSql collection totally depends on how you want to get the data. Two collections:
//doctors
{
_id: "SOMETHING",
name: "SOMETHING"
}
//appointments
{
_id: "SOMETHING",
doctorId: "", // ref of doctor collection
appointmentAt: "",
appointmentAtMilli: "",
}

How to retrieve multiple users at once with the GitHub API?

I'm able to get a single user, or all users created since a timestamp, or where there is some search match with the GitHub API.
https://developer.github.com/v3/users/#get-a-single-user
https://developer.github.com/v3/users/#get-all-users
https://developer.github.com/v3/search/#search-users
What I haven't been able to figure out is if there is a way to send something like a list of logins and get back all of those users at once.
My use case is that I'm pulling back a list of members off of an org. This provides me with enough data that I could loop through each individual user and get the detailed user data that I need this way, but I would rather not be hammering GitHub's API with a bunch of extra requests if it is not necessary.
Using GraphQL API v4, you could build a dynamic query with as many user you have in your array & use aliases for each one :
query {
user1: user(login: "aisalmi") {
...UserFragment
}
user2: user(login: "bertrandmartel") {
...UserFragment
}
user3: user(login: "molokoloco") {
...UserFragment
}
}
fragment UserFragment on User {
login
name
}
I also use a fragment to avoid field duplication
Test it in the explorer

How to make transactions on multiple data tables in Firebase?

I've an application, which uses Firebase. I have a new post adding. And when I make it, I do a number of operations in database, like:
Add new post info to Posts node
Add Id of the new post to Users node
Upload media to storage
etc.
So, for example, user can close application on step 2. How can I reset data on start of adding new post?
If I've understood correctly, Firebase transactions work on only one data table.
Main question is: how to make transactions on multiple data tables and storage in Firebase?
I believe you're looking for something like this: https://firebase.google.com/docs/database/web/read-and-write#update_specific_fields. It allows you to run multiple updates all at once to wherever you need. Here is a snapshot of the code:
var updates = {};
updates['/posts/' + newPostKey] = ...;
updates['/user-posts/' + uid + '/' + newPostKey] = ...;
return firebase.database().ref().update(updates);

Azure Mobile Web Services REST Results Per Page for Pagination

I am using Azure Mobile Web Services for my backend data exposed via REST/JSON. I have not been able to locate documentation that states how many results are posted per page, and how to page through them, as I need to incorporate server side paging for my Angular app.
GITs API has something as follows:
Requests that return multiple items will be paginated to 30 items by default. You can specify further pages with the ?page parameter. For some resources, you can also set a custom page size up to 100 with the ?per_page parameter.
Is there anything similar in Azure's Mobile Web Service API/Does anyone know the results per page and how to page thru them? Ex. https://myrestcall.net/tables/articles?page=2
If you are using the Javascript client you can check out this page
How to: Return data in pages
By default, Mobile Services only returns 50 rows in a given request, unless the client explicitly asks for more data in the response. The following code shows how to implement paging in returned data by using the take and skip clauses in the query. The following query, when executed, returns the top three items in the table.
var query = todoItemTable.take(3).read().done(function (results) {
alert(JSON.stringify(results));
}, function (err) {
alert("Error: " + err);
});
Notice that the take(3) method was translated into the query option $top=3 in the query URI.
The following revised query skips the first three results and returns the next three after that. This is effectively the second "page" of data, where the page size is three items.
var query = todoItemTable.skip(3).take(3).read().done(function (results) {
alert(JSON.stringify(results));
}, function (err) {
alert("Error: " + err);
});
Again, you can view the URI of the request sent to the mobile service. Notice that the skip(3) method was translated into the query option $skip=3 in the query URI.