Firebase data modeling for inequality check - firebase

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
}

Related

I need to all users and for each user all tokens in sequelize

I have a schema in sequelize that a user has many tokens, I need to get all users and for each user, I need to have all tokens. The id of user is saved in Token table as FK.
I created this below but did not work
await Model.Users.findAll({
attributes: ['id'],
include: [
{
model:Model.Token,
attributes: ['token']
}
]
});
The response I want to have back is like below
[
{ id: 2, Tokens: [{token: sdasdasdasdweqrewrfwe}, {token: test}] },
{ id: 6, Tokens: [{token: test2}, {token: test3}] },
.
.
]
Thanks
Problem was not in code but in sequelize table connection, if you have same problem please check the connection
db.User.hasMany(db.Token, {
onDelete: "CASCADE",
onUpdate: "CASCADE",
foreignKey: 'user_id'
});

Flutter Firestore understanding joins

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

Is there a way in Firebase Cloud Firestore to check if a Path is in an Array<Reference> of a document?

I'm trying to add security rules to a new Firestore project I'm working on. I have a collection named users that has all my user data in it in this format in my Firestore database:
var users = {
"userId": {
friend_requests: [],
friends: [
/users/friendId1,
/users/friendId2
],
name: "User One",
username: "user1"
},
"friendId1": {
friend_requests: [],
friends: [
/users/userId
],
name: "User Two",
username: "user2"
},
"friendId2": {
friend_requests: [],
friends: [
/users/userId
],
name: "User Three",
username: "user3"
},
"lonelyUser": {
friend_requests: [],
friends: [],
name: "Lonely User",
username: "lonely_user"
}
}
My Firestore rules are this, verbatim:
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
match /users/{userId} {
allow read: if isOwner(userId) || isFriendOf(userId);
}
}
function isOwner(userId) {
return userId == currentUser().uid;
}
function isFriendOf(userId) {
return getUserPath(userId) in getUserData().friends;
}
function currentUser() {
return request.auth;
}
function getUserData() {
return get(getUserPath(currentUser().uid)).data;
}
function getUserPath(userId) {
return /databases/$(database)/documents/users/$(userId);
}
}
The keys in the map I outlined above are Firebase user ids in my actual db, so when logged in as user "userId" I'd expect to be able to read the user document for both "friendId1" and "friendId2" users.
The problem I'm having is that isFriendOf is returning false. I've tried a few variants of wrapping the comparison data in a get call and passing in other values like id and data off the resource it returns.
I've also tried wrapping the getUserPath call in isFriendOf in a get and then using the __name__ property of the document as the comparison value as well. No luck there either.
Any help would be greatly appreciated.
Edit: Including a screenshot of the actual documents for clarification.
Screenshot of Firebase Documents
Edit 2: I've made a clean firebase project with only the information in these new screenshots in it. I'm including screenshots of Firebase Authentication page, both user entries in the database, as well as a failed simulator run as one user trying to get the document of the other user.
Authentication Configuration
user1
user2
Simulated Request

Firebase data structure and rules advice

I have just started developing my first app and have never used Firebase in the past. Before I get too far in to development I would like some advice on how to structure my Firebase data and rules.
The structure/rules need to allow users to upload their own posts, only the owner can update or delete their own posts and posts can be viewed both as a complete list or as a list of posts from the selected user.
A user can also set a post as a favourite, again only they can add or remove a favourite but other users can view a users favourites.
Below is the data structure so far:
{
users:{
'userId1':{ //Firebase assigned ID
'name': "user1",
'email': "user#email.com",
},
'userId2':{
'name': "user2",
'email': "user2#email.com",
}
},
posts:{
'postsId1':{ //Firebase assigned ID
'title': "title",
'message': "message text",
'userId': "userId1"
},
'postsId2':{
'title': "title2",
'message': "message text",
'userId' : "userId1"
},
},
'favourites': {
'userId1': {
'postsId1': "note about favourite",
'postsId2': "note about favourite"
}
'userId2': {
'postsId2': "note about favourite"
}
}
Thanks in advance.

Firebase notEqualTo alternative in schema

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.

Resources