I am building a social media app (very simple) an I want to store user's activity in firestore database. I have a collection of "users" and I keep user's id, user's username, user's profile pic there. But I dont think that user's activity should be stored there as well (correct me if I am wrong?)
So I created a new collection called UserActivity
where I store user's activity. I wanted to store if a user has been searching on a profile so I do the following:
const logUserSearch = async (term) => {
await firebase
.firestore()
.collection("userActivity")
.doc(firebase.auth().currentUser.uid)
.collection("userSearch")
.add({
term: term,
date: firebase.firestore.FieldValue.serverTimestamp(),
})
};
I think the above query solves the problem with user's search term's. However I want to store if a user has visited a profile. So here is my question: what is the correct way to store if a user visited a profile? Should I add new subcollection "profileVisit", something like that:
const logProfileVisit = async (searchTerm, profileId) => {
await firebase
.firestore()
.collection("userActivity")
.doc(firebase.auth().currentUser.uid)
.collection("profileVisit")
.doc(profileId)
.add({
source: searchTerm,
date: firebase.firestore.FieldValue.serverTimestamp(),
})
};
But then how do I calculate which are the most "popular" profiles? Should I create my database in another way, like this:
const logProfileVisit = async (searchTerm, profileId) => {
await firebase
.firestore()
.collection("userActivity")
.doc(profileId)
.collection("profileVisit")
.add({
user: firebase.auth().currentUser.uid
source: searchTerm,
date: firebase.firestore.FieldValue.serverTimestamp(),
})
};
So that I can easily calculate which are the most "popular" profiles? What about the user case where I need to calculate "top 10 fan profiles" or something similar? I.e. How do I calculate who visited your profile most often?
CodePudding user response:
A root level collection "userActivity" (or a sub-collection) should be enough. You can store the activity type as a field instead of sub-collections as shown below:
users -> {userId} -> userActivity -> {logId}
(col) (doc) (col) (doc)
But then how do I calculate which are the most "popular" profiles?
You can store a number field in that profile's document and whenever the logProfileVisit
is called, increment that:
const usersCol = firebase.firestore().collection("users")
const logProfileVisit = async (searchTerm, profileId) => {
await Promise.all([
usersCol
.doc(currentUserId)
.collection("userActivity")
.add({
source: searchTerm,
date: firebase.firestore.FieldValue.serverTimestamp(),
type: "profileVisit"
}),
usersCol
.doc(profileUserId)
.update({
profileViews: firebase.firestore.FieldValue.increment(1),
})
])
};
You can also use batch writes while updating these fields so either both the operations fail or pass.