I am creating app using Firebase database. This app is very similar to Tinder. You simply rate profiles and I need to query database for profile that user doesn't rated yet. My schema looks like this:
{
users: {
user1: {
alreadyRated: {user2: true, user3: true}
},
user2: {
alreadyRated: {user1: true}
}
},
userProfiles: {
user1: {
name: "John",
age: 20,
...
},
user2: {
name: "Jane",
age: 30,
...
}
}
}
So, if I am user2 I want get all profiles that I doesn't rated yet, in my example I want user3 profile. How to do that? Now I am downloading all profiles and filtering it on client side, but it's not good solution, because there could be hundred or thousands profiles in future. I think I should change my database schema, but I don't know how.
Thank you for ideas.
Related
I'm new in firebase, I know in mysql we have a table users with a unique id (eg: 1, 2...).
If I have a table follow and I want to record who follows who, I add:
follow
1 3 // user_id 1 follows user_id 3
3 2
3 1
I'd like the best approuch in firebase real time database, I have a json users, with unique key too and username. And I have json follow:
follow:
CMypCAlwMXPeM8X07P0sKsO
|
--- randomkey
|
--- follow: UFPRK8GG4tMvCejEfqWiCE220Mv2
in other words, user CMypCAlwMXPeM8X07P0sKsO follow user UFPRK8GG4tMvCejEfqWiCE220Mv2.
In firebase, should I work with this unique users keys (like mysql) or should I use usernames? like:
josh
|
... randomkey
|
--- follow: marie
thanks!
To model followers between users in Firebase Realtime Database, I typically end up with three top-level lists:
users: {
uid1: { ... },
uid2: { ... },
uid3: { ... }
},
followers: {
uid1: {
uid2: true
},
uid2: {
uid3: true,
},
uid3: {
uid1: true
}
},
followees: {
uid1: {
uid3: true
},
uid2: {
uid1: true,
},
uid3: {
uid2: true
}
}
So you're essentially splitting your single follow table into two top-level lists: one for each "direction" of the relationship.
Also see:
Many to Many relationship in Firebase
Firebase simple many to many relationship
I am doing this in Flutter, with a Firebase database, using the Firestore packages in Flutter. I would like to know how a join is done in noSQL (or more specifically, in Flutter-Firestore)
This is what my database looks like:
users: {
U1: {
name: 'Peter',
surname: 'Jensen'
},
U2: {
name: 'Marry',
surname: 'Kown'
},
...
}
groups: {
G1: {
name: 'Group 1'
},
G2: {
name: 'Group 2'
},
...
}
members: {
M1: {
userId: U1,
groupId: G1
},
M2: {
userId: U1,
groupId: G2
},
M3: {
userId: U2,
groupId: G1
},
...
}
Now how do I do a join to get something like this:
members: {
M1: {
userId: {
name: 'Peter',
surname: 'Jensen'
},
groupId: {
name: 'Group 1'
}
},
M2: {
userId: {
name: 'Peter',
surname: 'Jensen'
},
groupId: {
name: 'Group 2'
}
},
M3: {
userId: {
name: 'Marry',
surname: 'Kown'
},
groupId: {
name: 'Group 1'
}
},
...
}
Do I do:
const users = await Firestore.instance.collection('users').getDocuments();
const groups = await Firestore.instance.collection('groups').getDocuments();
const members = await Firestore.instance.collection('members').getDocuments();
...manually loop through everything and assign everything myself
(I need to add more text because I have 'mostly code'): I would assume the above would use of a lot of query data in Firebase, so I can't see how this would be a good idea. I actually just want to see in what groups is a user a in
If you have groups and members, I'd typically store the follow data:
A list of users in a users collection.
For each user I'd keep their properties and a list of the group IDs of the groups they're a member of.
A list of groups in a groups collection.
For each group I'd keep their properties
Note that you could model the nested list as a subcollection, but typically this is not needed. With the above model you can easily find what groups a user is part of, even even do a query for users who are part of a certain group with an array-contains clause.
To get a list of the properties of the group for a specific user, you'll indeed need to load that user, and their groups separately. This is normal with many NoSQL databases, and not necessarily as slow as you may expect. But if performance is not good enough, you can consider duplicating some data to reduce the need for joins. It all depends on your needs, and unlike in relational data models, NoSQL is not dogmatic about such things.
To learn more about this topic:
read NoSQL data modeling
watch Getting to know Cloud Firestore
We have an application that will store data on Firebase (database) that will then be queried later.
What is the correct format to store the data in.
The example data will be completedGames. They will have data such as:
UserId
TimeToComplete
GameData
Etc...
The query later will then look for all completed games by UserId. We want to ensure the data is collected in the best way possible to query later, rather than refactoring later.
In your case, first off - be sure you have a good reason to use Firebase over Firestore. Once you're confident you should stick with Firebase Realtime Database, look at the below excerpt of documentation. So, you might actually have 2 separate parent nodes, 1 for userId and another for games. Each game node's child is a particular game, which has a child tree of game users (by userId).
Flatten data
structures
If the data is instead split into separate paths, also called
denormalization, it can be efficiently downloaded in separate calls,
as it is needed. Consider this flattened structure:
{
// Chats contains only meta info about each conversation
// stored under the chats's unique ID
"chats": {
"one": {
"title": "Historical Tech Pioneers",
"lastMessage": "ghopper: Relay malfunction found. Cause: moth.",
"timestamp": 1459361875666
},
"two": { ... },
"three": { ... }
},
// Conversation members are easily accessible
// and stored by chat conversation ID
"members": {
// we'll talk about indices like this below
"one": {
"ghopper": true,
"alovelace": true,
"eclarke": true
},
"two": { ... },
"three": { ... }
},
// Messages are separate from data we may want to iterate quickly
// but still easily paginated and queried, and organized by chat
// conversation ID
"messages": {
"one": {
"m1": {
"name": "eclarke",
"message": "The relay seems to be malfunctioning.",
"timestamp": 1459361875337
},
"m2": { ... },
"m3": { ... }
},
"two": { ... },
"three": { ... }
}
}
i've been developing a mobile app with react native & firebase realtime db, and i'm stuck with a data-modeling problem.
My app will let users to vote photos that uploaded by other users and each user will be allowed to vote once for each photo. I'm providing a tinder-like UI for voting action. I'm planning to have users and photos trees on the firebase looks like this, which is pretty straight forward:
{
users:{
userId1: {
name:'John'
surname: 'Doe',
votedPhotos: {
somePhotoId: {
timestamp: 1528836856000
},
somePhotoId2: {
timestamp: 1529363754000
},
...
},
...
},
userId2: {
name:'Johnny'
surname: 'Doerr'
...
},
...
},
photos: {
photoId1: {
url: 'https://a-firebase-storage-url',
owner: {
uid: 'userId1',
fullName: 'John Doe'
},
upvoteCount: 12,
downvoteCount: 8
},
photoId2: {
url: 'https://another-firebase-storage-url',
owner: {
uid: 'userId2',
fullName: 'Johnny Doerr'
},
upvoteCount: 28,
downvoteCount: 4
},
...
}
}
I need to prevent users to vote their own photos and vote a photo more than once. So i need to query photos as excluding already voted photos and self uploaded photos for a user. If i was using a traditional db it would be easy as a pie but i couldn't figure out how to do that query in a firebase realtime database since i can't use not_equals or not_in. How would you suggest me to model my data?
Record user votes under the photouid. I imagine a .length could provide you the total votes.
photos
photo1-uid
owner:user1-uid
votes:{
user2-uid: true,
user3-uid: true
}
I would like to give permissions to users based on their usergroups.
Simply checking if a user is a member of that group wouldn't work though, as I want to be able to dynamically create usergroups and set their permissions (without having to change the Firebase Rules).
That's how my data is structured:
users: {
user_1: {
name: "John Smith",
creation_date: "1234567890000"
usergroups: {
usergroup_1: true,
usergroup_4: true
}
}
...
}
usergroups: {
usergroup_1: {
name: "admin",
creation_date: "1234567890000"
permissions: {
manage_users: true,
manage_chat: true,
manage_calendar: true,
...
}
}
usergroup_2: {
name: "moderator",
creation_date: "1234567890000"
permissions: {
manage_chat: true
}
}
...
}
Note that users may have more than one usergroup, each with a different set of permissions (might be the same).
An example: users will only be able to manage the chat if they are in at least one usergroup that allows them to do so.
Any idea on how I could accomplish this? Maybe by structuring the data on a different way?