0

I'm trying to build (offline first) chat application with react native (and nodeJS, mongoDB, socketIO).

I want to ask what is the best (optimized) way to fetch friends list.

my user model structure:

mongoose.Schema({
    phoneNumber: Number,
    friends: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User'
    }],
})

as json

[
    {
        "_id": ObjectId("5e91bcd6cd1630213d95f810"),
        "phoneNumber": "+995555555555",
        "friends": [
            ObjectId("5e57d64d92cc878760086980"),
            ObjectId("5e57d64d92cc878760086981")
        ]
    },
    ...
]

My current approach is I fetch friends list from api and save to localStorage when a user boot the application. So, user can see friends list even if they are offline.

And my concern is if there's 1000 users and they have 200 users in their friend list it would be expensive call.

I can only update localStorage when the user add a friend, but the user won't be able to see if a friend change their avatar or username, etc..

So, what is the best way to keep up-to-date friend list?

1
  • Hey @Kakajann have you managed to make any progress? Commented Apr 17, 2020 at 18:06

1 Answer 1

2

Maybe you could change your structure to have a Connections collection which stores a pair of userIds. I can't say this would be more optimal but it does leave you more room for expansion, for example this would support having connection types, some connections might be friends, others could be from message chains between people who are not friends, not sure what you'd call this exactly but think of something like message requests in Facebook messenger as an example.

Another advantage of this is it stops you creating an accidental megadoc as someone's friend list gets bigger and bigger. It also means that when you fetch a friend user doc you won't also be fetching that friends friends, perhaps this is where the optimisation you're looking for is.

Connections could look something like this:

{
    instigator: ObjectId("5e91bcd6cd1630213d95f810"),
    subordinate: ObjectId("5e57d64d92cc878760086980"),
    type: 'friendship'
}

{
    instigator: ObjectId("5e91bcd6cd1630213d95f810"),
    subordinate: ObjectId("5e57d64d92cc878760086981"),
    type: 'friendship'
}

to represent the two friendships in your example.

To get the friends of one user you would query something like Connections.find({ users: ObjectId('5e91bcd6cd1630213d95f810'), type: 'friendship' })

You could use an aggregate or mongoose populate to swap the userIds out for their docs before returning them to the client.

Sign up to request clarification or add additional context in comments.

1 Comment

Hi. I decided to fetch the friends party.. like pagination. For example: Let's say a user has 200 friends. I keep them all in localStorage. When the user boot the app, I only fetch first 10 friends, and update the first 10 friends in localStorage. And keep fetch the rest as the user scrolls. I think it's the best way to keep data up-to-date. I Also check whatsapp and telegram. They don't update avatar, etc. immediately. It takes little time to update as i scroll.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.