Структурирование Firebase на заказ по времени последнего лайка и два последних лайка - PullRequest
0 голосов
/ 22 марта 2020

У меня есть социальное приложение, которое я хочу показать пользователю сообщения, которые понравились ему в последнее время, и которые были двумя последними людьми, которым понравился этот пост. Отображалось что-то вроде «Пользователю A и пользователю B понравились, а вашему посту понравились 31 человек», где 31 участнику понравилась эта публикация не так давно, как пользователю A и пользователю B, и эта запись c была самой последней публикацией пользователя, которая ему понравилась .

Я пытаюсь найти наилучший способ структурирования базы данных с учетом этих требований. Я думал, что сохраню метку времени lastLiked, связанную с постом, в likeActivity, а затем использую метку времени в качестве ключа для пользователей, которым понравился пост (см. Ниже).

  "likeActivity" : {
    "nIhx1SnChjapy4cbrD5sC1WIZXM2" : {
      "-M0egnxw7TqEJoEwA0gG" : {
        "lastLiked" : 1582337525620,
        "userLikes" : {
          "1582337525616" : "BmvRlWWuGRWApqFvtT8mXQlDWzz2",
          "1582337525620" : "Ff0CxZhQzYVHuqbnsiOKwRAB01D2"
        }
      },
      "-M0jMrisNrnB4usGeCaS" : {
        "lastLiked" : 1582337525630,
        "userLikes" : {
          "1582337525630" : "Ff0CxZhQzYVHuqbnsiOKwRAB01D2"
        }
      },
      "-M0jPBatN45YtfdyTXNM" : {
        "lastLiked" : 1582337525616,
        "userLikes" : {
          "1582337525610" : "bz2E02wmmXQjVkxRF23T2SPkzSf2",
          "1582337525616" : "WPOThFRRLDUCeJ8YVmyHFpGgnxI3"
        }
      }
    }
  }

Будет ли это наилучшим образом, учитывая мои требования сверху? Если это так, у меня возникла масса проблем с поиском их для моего приложения iOS, потому что когда я звоню snapshot.children.allObjects, я получаю не только likes, но и отметку времени lastLiked. Как бы я переработал функцию observeActivity для извлечения данных, упорядоченных по lastLiked, а затем по timestamp. Я прочитал документацию по заказу данных в Firebase, но я не уверен, как применить ее в моих обстоятельствах.

func observeActivity () {
    guard let uid = Auth.auth().currentUser?.uid else {
        return
    }

    let newActivity = DataService.ds.REF_LIKE_ACTIVITY.child("\(uid)")

    newActivity.observe(.value, with: {(snapshot) in

        self.posts = []

        if let snapshot = snapshot.children.allObjects as? [DataSnapshot] {

            for snap in snapshot{

                let postKey = snap.key
                //self.posts.append(snap.key)

                let userLikeData = newActivity.child("\(snap.key)").child("userLikes")

                userLikeData.observe(.value, with:  {(snapshot) in

                    if let newSnap =  snapshot.children.allObjects as? [DataSnapshot] {

                        for valueSnap in newSnap {
                            //Users who have liked the post
                            print("SNAPTIVITY \(valueSnap.value!)")
                            let userId = valueSnap.value!
                            //self.userArray.append("\(userId)")

                            if self.activityDict["\(postKey)"] != nil {
                                self.activityDict["\(postKey)"]!.append("\(userId)")
                            } else {
                                self.activityDict["\(postKey)"] = ["\(userId)"]
                            }

                        }
                        let postData = DataService.ds.REF_POSTS.child(postKey)
                        postData.observe(.value, with: { (snapshot) in
                            if let postDict = snapshot.value as? Dictionary<String, AnyObject> {
                                let key = snapshot.key
                                let post = Post(postKey: key, postData: postDict, isLiked: 0)
                                self.posts.append(post)
                            }


                            //self.feedTableView.reloadData()
                            self.activityTableView.reloadData()
                        })
                    }

                })
            }
        }

    })


}

1 Ответ

1 голос
/ 23 марта 2020

В большинстве приложений социальных сетей каждому пользователю может понравиться только один пост. Ваша текущая модель данных для таких лайков:

"userLikes" : {
  "1582337525616" : "BmvRlWWuGRWApqFvtT8mXQlDWzz2",
  "1582337525620" : "Ff0CxZhQzYVHuqbnsiOKwRAB01D2"
}

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

По этой причине довольно жесткое правило при моделировании данных в Firebase & Firestore: если что-то должно быть уникальным, это должен быть ключ дочернего узла / документа .

Итак, исходя из этого, я бы смоделировал этот фрагмент как:

"userLikes" : {
  "BmvRlWWuGRWApqFvtT8mXQlDWzz2": 1582337525616,
  "Ff0CxZhQzYVHuqbnsiOKwRAB01D2": 1582337525620
}

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


Я предполагаю, что ваша структура данных:

likeActivity
  $uid
    $postId: ...

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

Таким образом, вы можете сортировать сообщения по их lastLiked, но затем вы не можете определить порядок, в котором возвращаются userLikes. Вам нужно изменить порядок этих результатов в коде приложения, чтобы определить самый последний тип (r).

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