I am planning to develop production ready hybrid ionic3 mobile application similar to instagram using firebase. I chose firestore nosql for storing data and querying.
I have experience designing schema in RDMS ( ignore second green colored user table ). But I am struggling to design NoSql schema for my application. Below I added RDMS schema that I want to convert it to nosql.
There are several queries I want to make efficiently.
Simple Sql query for above list
Select * from photo LIMIT=50
How should I approach to convert photo and user table to firestore NoSql OR NoSql in order to query efficiently?
Cloud Firestore is a NoSQL, document-oriented database. Unlike a SQL database, there are no tables or rows. Instead, you store data in documents, which are organized into collections. Each document contains a set of key-value pairs.
How does it work? Cloud Firestore is a cloud-hosted, NoSQL database that your Apple, Android, and web apps can access directly via native SDKs.
All Firebase Realtime Database data is stored as JSON objects. You can think of the database as a cloud-hosted JSON tree.
The key differences between Firebase and MySQL: Architecture: Firebase is a NoSQL database that stores and syncs data in real-time (a real-time document store); MySQL is an open-source relational database management system based on the domain-specific language SQL.
Here is a proposal:
One Collection named photos
with photo
documents that have:
creation
field holding a date (i.e. a timestamp)tags
field as an object with key-value pairs like {black: true, cats: true}
, see this help doc for the rationale: https://firebase.google.com/docs/firestore/solutions/arrays. The HTML code below shows how to use/query itcomments
One Collection named users
with user
documents that have:
uid
from the authentication)followedUsers
object holding the ids of the users followed by the current user {userId1: true, userId2: true}
followedPhotosId
object holding the ids of the photos followed by the current user {9HzWzyXmcnBDuhTZKoQw: true, fO0OvzJs9M8p9N0jufte: true}
followedPhotos
sub-collection holding the details of the followed photosThe following HTML page shows how to execute the queries you list in your post, as well as some queries reading and writing data: these latest queries should be used in several Cloud Functions dedicated to keeping the followedPhotosId
objects and followedPhotos
Collections in synch when a user follows a new other user and/or when a user (followed by one or more users) adds or deletes a photo.
<html>
<head>
<!-- Firebase App is always required and must be first -->
<script src="https://www.gstatic.com/firebasejs/5.3.0/firebase-app.js"></script>
<!-- Add additional services that you want to use -->
<script src="https://www.gstatic.com/firebasejs/5.3.0/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.3.0/firebase-database.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.3.0/firebase-firestore.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.3.0/firebase-functions.js"></script>
</head>
<body>
<script>
// Initialize Firebase
var config = {
apiKey: "",
authDomain: "xxxxx.firebaseapp.com",
databaseURL: "https://xxxx.firebaseio.com",
projectId: "xxxxxx"
};
firebase.initializeApp(config);
var firestoredb = firebase.firestore();
firestoredb.collection("photos").orderBy("creation", "desc")
.get()
.then(function(querySnapshot) {
console.log("YOUR QUERY #1");
querySnapshot.forEach(function(doc) {
// doc.data() is never undefined for query doc snapshots
console.log(doc.id, " => ", doc.data());
});
})
.catch(function(error) {
console.log("Error getting documents: ", error);
});
firestoredb.collection("users").doc("user1").collection("followedPhotos")
.get()
.then(function(querySnapshot) {
console.log("YOUR QUERY #2");
querySnapshot.forEach(function(doc) {
// doc.data() is never undefined for query doc snapshots
console.log(doc.id, " => ", doc.data());
});
})
.catch(function(error) {
console.log("Error getting documents: ", error);
});
firestoredb.collection("photos")
.where('tags.cats', '==', true) //You should create a photo with a "cats" tag
.get()
.then(function(querySnapshot) {
console.log("YOUR QUERY #3");
querySnapshot.forEach(function(doc) {
// doc.data() is never undefined for query doc snapshots
console.log(doc.id, " => ", doc.data());
});
})
.catch(function(error) {
console.log("Error getting documents: ", error);
});
firestoredb.collection("photos").orderBy("creation", "desc").limit(50)
.get()
.then(function(querySnapshot) {
console.log("YOUR QUERY #4, i.e; Select * from photo LIMIT=50");
querySnapshot.forEach(function(doc) {
// doc.data() is never undefined for query doc snapshots
console.log(doc.id, " => ", doc.data());
});
})
.catch(function(error) {
console.log("Error getting documents: ", error);
});
firestoredb.collection("users")
.where('followedUsers.user2', '==', true)
.get()
.then(function(querySnapshot) {
console.log("Get all the users who follows user2. To use in the Cloud Function");
querySnapshot.forEach(function(doc) {
// doc.data() is never undefined for query doc snapshots
console.log(doc.id, " => ", doc.data());
});
})
.catch(function(error) {
console.log("Error getting documents: ", error);
});
firestoredb.collection("users")
.where('followedPhotosId.9HzWzyXmcnBDuhTZKoQw', '==', true)
.get()
.then(function(querySnapshot) {
console.log("Get all the users who follow photo with Id 9HzWzyXmcnBDuhTZKoQw. To use in the Cloud Function");
querySnapshot.forEach(function(doc) {
// doc.data() is never undefined for query doc snapshots
console.log(doc.id, " => ", doc.data());
});
})
.catch(function(error) {
console.log("Error getting documents: ", error);
});
firestoredb.collection("users").doc("user1").get().then(function(doc) {
if (doc.exists) {
console.log("Update the followedPhotosId object for user1 after a user she/he follows has added a photo with id abcdefghijklmn. To use in the Cloud Function");
var followedPhotosId = doc.data().followedPhotosId;;
Object.assign(followedPhotosId, {abcdefghijklmn: true});
firestoredb.collection("users").doc("user1").set({followedPhotosId: followedPhotosId});
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
}
}).catch(function(error) {
console.log("Error getting document:", error);
});
</script>
<body>
</html>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With