Как отсортировать данные в Firebase? - PullRequest
0 голосов
/ 01 декабря 2018

Теперь я могу сортировать сообщения и пользователей по времени.

Моя структура данных выглядит так:

posts
 -postId
     imageRatio: 
     imageUrl: 
     postText: 
     postTime: 
     uId:
users
 -UserId
    email: 
    profileImageURL: 
    radius: 
    uid: 
    username: 
    username_lowercase: 

ОБНОВЛЕНИЕ

Теперь я создал новый класс со всеми данными для пользователя и сообщениями:

class UserPostModel {
    var post: PostModel?
    var user: UserModel?

    init(post: PostModel, user: UserModel) {
        self.post = post
        self.user = user
    }
}

Объявление массива сообщений:

var postArray = [UserPostModel]()

Здесь я загружаю данные вновый класс:

self.observeRadius(completion: { (radius) in
                let currentRadius = radius
            // Üperprüfe, welche Posts im Umkreis erstellt wurden
                let circleQuery = geoRef.query(at: location!, withRadius: Double(currentRadius)!)

            circleQuery.observe(.keyEntered, with: { (postIds, location) in

                self.observePost(withPostId: postIds, completion: { (posts) in
                    guard let userUid = posts.uid else { return }
                    self.observeUser(uid: userUid, completion: { (users) in
                        let postArray = UserPostModel(post: posts, user: users)
                        self.postArray.append(postArray)
                        print(postArray.post!.postText!, postArray.user!.username!)
                        self.postArray.sort(by: {$0.post!.secondsFrom1970! > $1.post!.secondsFrom1970!})

                    })
                })

Здесь я загружаю данные в ячейки табличного представления:

    extension DiscoveryViewController: UITableViewDataSource {
    // wie viele Zellen
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print(postArray.count)
        return postArray.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "DiscoveryCollectionViewCell", for: indexPath) as! DiscoveryCollectionViewCell

        cell.user = postArray[indexPath.row]
        cell.post = postArray[indexPath.row]
        //cell.delegate = self

        return cell
    }
}

Заранее спасибо за помощь!

1 Ответ

0 голосов
/ 01 декабря 2018

В вопросе много кода, а иногда проще, тем лучше.Итак, давайте возьмем класс Post, загрузим сообщения, получим имя пользователя и сохраним его в массиве.Затем по завершении сортируйте и распечатывайте сообщения в обратном хронологическом порядке.

Класс для хранения данных записи и имени пользователя

class PostClass {
    var post = ""
    var timestamp: Int! //using an int for simplicity in this answer
    var user_name = ""

    init(aPost: String, aUserName: String, aTimestamp: Int) {
        self.post = aPost
        self.user_name = aUserName
        self.timestamp = aTimestamp
    }
}

Обратите внимание, что если мы хотим, чтобы оба сообщенияданные и пользовательские данные, мы могли бы сделать это

class PostUserClass {
   var post: PostClass()
   var user: UserClass()
}

, но мы оставим это простым для этого ответа.

Затем массив для хранения сообщений

var postArray = [PostClass]()

и, наконец, код для загрузки всех постов, получения связанного имени пользователя (или объекта пользователя в полном примере).

let postsRef = self.ref.child("posts")
let usersRef = self.ref.child("users")
postsRef.observeSingleEvent(of: .value, with: { snapshot in
    let lastSnapIndex = snapshot.childrenCount
    var index = 0
    for child in snapshot.children {
        let childSnap = child as! DataSnapshot
        let uid = childSnap.childSnapshot(forPath: "uid").value as! String
        let post = childSnap.childSnapshot(forPath: "post").value as! String
        let timestamp = childSnap.childSnapshot(forPath: "timestamp").value as! Int
        let thisUserRef = usersRef.child(uid)

        thisUserRef.observeSingleEvent(of: .value, with: { userSnap in
            index += 1
            //for simplicity, I am grabbing only the user name from the user
            //  data. You could just as easily create a user object and
            //  populate it with user data and store that in PostClass
            //  that would tie a user to a post as in the PostUserClass shown above
            let userName = userSnap.childSnapshot(forPath: "Name").value as! String
            let aPost = PostClass(aPost: post, aUserName: userName, aTimestamp: timestamp)
            self.postArray.append(aPost) //or use self.postUserArray to store
                                         //  PostUserClass objects in an array.
            if index == lastSnapIndex {
                self.sortArrayAndDisplay() //or reload your tableView
            }
        })
    }
})

, а затем маленькая функция сортировки и печати в консоль

func sortArrayAndDisplay() {
    self.postArray.sort(by: {$0.timestamp > $1.timestamp})

    for post in postArray {
        print(post.user_name, post.post, post.timestamp)
    }
}

Обратите внимание, что Firebase является асинхронным, поэтому перед сортировкой / печатью мы должны знать, что мы загрузили все данные.Это обрабатывается с помощью lastSnapIndex и индекса.Индекс увеличивается только после того, как каждый пользователь загружен, и когда все сообщения и пользователи загружены, мы затем сортируем и печатаем по мере завершения данных.

В этом примере избегаются грязные обратные вызовы и обработчики завершения, которые могут вносить вкладк вопросу в вопросе - этот фрагмент кода является подозрительным и, вероятно, его следует избегать из-за асинхронной природы Firebase;Функция сортировки будет вызываться задолго до загрузки всех пользователей.

UserApi.shared.observeUserToPost(uid: userUid) { (user) in
    self.postUser.append(user)
}
self.postUser.sort(by: {$0.postDate! > $1.postDate!})

* добавьте проверку ошибок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...