Извлеченные данные из firebase иногда не добавляются в ячейку, несмотря на то, что они были извлечены ранее

#ios #swift #firebase #firebase-realtime-database

# #iOS #swift #firebase #firebase-realtime-database

Вопрос:

Я извлекаю данные из firebase следующим образом :

 fetchUsers (gets UIDs of people the current user follows)
  -for each user fetch his posts
     -for this user fetch his personal user-data (like profile image and username)
 

Примечание: я перезагружаю данные после вызова команды «для каждого пользователя извлекать его сообщения» и внутри нее для каждого сообщения.

Теперь вот странная часть. Внутри метода, показанного ниже, который вызывается при запросе firebase необходимых данных, есть операторы печати, показывающие данные. При просмотре этих данных они всегда присутствуют по мере необходимости (URL-адрес изображения профиля, а также имя пользователя и т. Д.).

     func addUserDataToObject(userObj: User, snapshot: DataSnapshot) {
    if (snapshot.childSnapshot(forPath: "username").value as! String) != "" {
        userObj.profileImageUrlString = "(snapshot.childSnapshot(forPath: "profileImage").value as! String)"
        userObj.fullName = "(snapshot.childSnapshot(forPath: "fullName").value as! String)"
        userObj.username = "(snapshot.childSnapshot(forPath: "username").value as! String)"
        print("(snapshot.childSnapshot(forPath: "profileImage").value as! String)", " this was wireed")
    } else {
        print("the username was nil!")
    }
}
 

Однако, когда я затем пытаюсь использовать эти данные в методах CollectionView, они не существуют:
Я печатаю:

                 print(postArray[indexPath.item].user.username, " This is supposed to be the username")
            print(postArray[indexPath.item].user.profileImageUrlString!, " This is supposed to be the URL")
            print(date, " This is supposed to be the date")
 

Все это будет «случайным образом» печатать пустые строки. Иногда я должен отметить, что они работают. Я обнаружил, что последовательно первый элемент ячейки работает отлично, а остальные 2 — нет.

Почему это происходит и как мне это исправить?

Обновить:

Вот часть запрошенного кода:

     func fetchAllUserFirstPostMedia(user: String) {
    print("2344 fetch called 32424243242")

    let databaseN = Database.database().reference()

    databaseN.child("Posts").child(user).observe(.value, with: {(snapshot) in

        guard snapshot.value as? [String: AnyObject] != nil else { return print("(snapshot.value) <-- this is snapshot.value in return statement") }

        let userUID = user
        if user == userUID {

            guard let postDictionary = snapshot.value as? [String:AnyObject] else { return }

            for anyPosts in postDictionary {
                print("inside the anyPosts")//will print as many times as there are posts.

                let currentPost = Post()

                let userObj = User(theuserID: userUID)
                self.retrieveUsersInfo(userObj: userObj)
                print(userObj.profileImageUrlString, " This is teh uirl for prof image")//this is Always empty (even though at leaased the first value has an image dysplayed and all seem to ahve had one when in the retriveUsersInfo() method)
              ...
 

Update2:

Я обнаружил, что проблема возникает только со средними 2 элементами (это всегда верно: -> индексы 1 и 2 всегда имеют проблему, независимо от того, каким может быть n) в представлении коллекции (если в нем 4 элемента. Больше элементов приводит к тому, что проблема возникает только у элементов 1 и 2)

Комментарии:

1. Привет .. можете ли вы поделиться кодом, в котором вы добавляете объект User в свой массив. Значения переопределяются из какой-либо другой части вашего кода

2. Что делает функция «retrieveUsersInfo»?

3. ref.child(«Users»).child(UID).observe(.value, с помощью: { (snapshot) в do { self.addUserDataToObject(userObj: userObj, snapshot: snapshot) } }) @Nivrutti

Ответ №1:

Ваш retrieveUsersInfo(userObj: User) метод асинхронный, поэтому данные, используемые для заполнения collectionView , вероятно, не загружаются вовремя.

Попробуйте переписать свой retrieveUsersInfo метод как замыкание, а затем выполнить итерацию по словарям post, как только будет найдена информация вашего пользователя (я не знаю, что вы делаете с anyPosts объектами, которые вы просматриваете, но вот что у меня есть):

 func fetchAllUserFirstPostMedia(user: String) {
    print("2344 fetch called 32424243242")

    let ref = Database.database().reference()

    ref.child("Posts/(user)").observe(.value, with: { snapshot in

        guard let postDictionary = snapshot.value as? [String:AnyObject] else {
            print("(snapshot.value) <-- this is snapshot.value in return statement")

            return
        }

        let userObj = User(theuserID: user)
        var posts = [Post]()

        self.retrieveUsersInfo(userObj: userObj) {
            print(userObj.profileImageUrlString)

            for anyPosts in postDictionary {
                print("inside the anyPosts")

                let currentPost = Post()

                // do whatever you need to do with anyPosts, currentPost, and userObj

                // add post object to array
                posts.append(currentPost)
            }

            print(posts) // all of your posts with the complete userObj
        }
    })
}

func retrieveUserInfo(userObj: User, completion: @escaping () -> Void) {
    let ref = Database.database().reference()
    // I'm assuming this UID object is the userObj's uid and it's coming from somewhere else?
    ref.child("Users").child(UID).observe(.value, with: { snapshot in
        self.addUserDataToObject(userObj: userObj, snapshot: snapshot)
        completion()
    })
}
 

Пара вещей, которые я изменил в вашем fetchAllUserFirstPostMedia методе:

  • вам не нужно проверять два оператора защиты, если значение моментального снимка завершается
  • вы устанавливаете константу userUID равной user , поэтому оператор if if user == userUID всегда будет успешным
  • установите userObj константу перед циклом, чтобы она не устанавливала каждую итерацию цикла.

Комментарии:

1. Моя единственная жалоба заключается в том, что скорость выборки непоследовательна. Иногда (при неизменном количестве сообщений) они извлекаются быстро, в других случаях медленно. есть идеи, почему?

2. Иногда это происходит медленнее, потому что ваш телефон обменивается данными с сервером, и скорость сети будет меняться. Мне нравится использовать UIActivityIndicators между временами загрузки для очистки такого рода материалов

3. Вы уверены? Потому что я испытываю все эти колебания, сидя на одном и том же месте. И когда он медленный, он замедляется на 10 или 20 секунд

4. Это может зависеть от того, что вы делаете с этими данными postDictionary после извлечения данных userObj. Если это не так, это может зависеть от другого выполняемого вами асинхронного вызова. Если вы опубликуете остальную часть своего кода в этом методе / сообщите мне репозиторий git, я посмотрю.