Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Observing every post on its own: is it effective? #2

Closed
MHX792 opened this issue Jan 4, 2017 · 6 comments
Closed

Observing every post on its own: is it effective? #2

MHX792 opened this issue Jan 4, 2017 · 6 comments

Comments

@MHX792
Copy link

MHX792 commented Jan 4, 2017

I just looked through your code and saw that you add an observer for every post in the user's stream. When a user follows 100 other users who posted like 10 pics each, this means you will need to have 1000 observers.

Is this really a good approach?

@mownier
Copy link
Owner

mownier commented Jan 4, 2017

I did not get what you actually mean. But AFAIK, there is no observer added every post. What is happening when a user follows is that, all the posts of the followed user will be copied/put into the feed of the logged in user.

@mownier
Copy link
Owner

mownier commented Jan 4, 2017

To understand what you mean, a code snippet could help.

@MHX792
Copy link
Author

MHX792 commented Jan 10, 2017

In PostServiceProdiver.swift you have written:

func fetchPosts(userId: String, offset: String, limit: UInt, callback: ((PostServiceResult) -> Void)?) {
    var result = PostServiceResult()
    guard session.isValid else {
        result.error = .authenticationNotFound(message: "Authentication not found")
        callback?(result)
        return
    }
    
    let uid = session.user.id
    let rootRef = FIRDatabase.database().reference()
    let usersRef = rootRef.child("users")
    let postsRef = rootRef.child("posts")
    let photosRef = rootRef.child("photos")
    let userPostRef = rootRef.child("user-post/\(userId)/posts")
    var query = userPostRef.queryOrderedByKey()
    
    if !offset.isEmpty {
        query = query.queryEnding(atValue: offset)
    }
    
    query = query.queryLimited(toLast: limit + 1)
    query.observeSingleEvent(of: .value, with: { (data) in
        guard data.childrenCount > 0 else {
            result.posts = PostList()
            callback?(result)
            return
        }
        
        var posts = [Post]()
        var users = [String: User]()
        
        for child in data.children {
            guard let userPost = child as? FIRDataSnapshot else {
                continue
            }
            
            let postId = userPost.key
            let postRef = postsRef.child(postId)
            
            postRef.observeSingleEvent(of: .value, with: { (postSnapshot) in
                guard let posterId = postSnapshot.childSnapshot(forPath: "uid").value as? String,
                    let photoId = postSnapshot.childSnapshot(forPath: "photo_id").value as? String else {
                        return
                }
                
                let userRef = usersRef.child(posterId)
                let photoRef = photosRef.child(photoId)
                let likesRef = rootRef.child("post-like/\(postId)/likes")
                
                userRef.observeSingleEvent(of: .value, with: { (userSnapshot) in
                    photoRef.observeSingleEvent(of: .value, with: { (photoSnapshot) in
                        likesRef.observeSingleEvent(of: .value, with: { (likesSnapshot) in
                        
                            //...
                        })
                    })
                })
            })
        }
    })
}

You are chaining observers. For every post you have 3 additional observers. If there are 100 posts in your stream, this means that you will have at least 400 observers.

Isn't this too much?

See this related SO question:

http://stackoverflow.com/questions/41558394/firebase-best-way-for-observing-post-metadata-in-a-social-network

@mownier
Copy link
Owner

mownier commented Jan 11, 2017

@MHX792 Yep, I already got your point. This function will produce a large amount of observers. I guess the implementation of post pagination using the offset and limit parameters makes the function effective. If you just limit your fetch up to 10, you have only 40 observers per fetch. I think that is fair enough.

@MHX792
Copy link
Author

MHX792 commented Jan 12, 2017

But fetching only 10 posts is way to insufficient. It should show at least the latest 50 posts which would result in having 200 observers. Isn't there any other way to do this?
How about embedding the likes and other data in the posts?
The downside would be that likes need to be updated in different nodes when somebody (un-)likes a post.

@mownier
Copy link
Owner

mownier commented Jan 13, 2017

I think there is way. You can implement by having a queue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants