Как сделать последовательный запрос firebase в swift?

#swift #firebase #firebase-realtime-database #sequential

# #быстрый #огневая база #firebase-realtime-database #последовательный

Вопрос:

Ниже приведена моя структура данных:

 {    
    "posts": {

        "xyz1": {
          "author": "Jan",
          "uid": "abc123",
        },
        "xyz2": {
          "author": "Jenny",
          "uid": "abc456",
        },

      }

    "users": {
        "abc123": {
          "email": "Jan@gmail.com",
          "profilePicURL": "https://firebasestorage.googleapis.com/v0/b/",
        },
        "abc456": {
          "email": "Jenny@gmail.com",
          "profilePicURL": "https://firebasestorage.googleapis.com/v0/c/",
        },
      }    
}
 

Я хочу отобразить список записей «posts» в tableview.

  let postRef = ref.child("posts")

        postRef.observe(.childAdded, with: { (snapshot) in
            let authorText = snapshot.value!.object(forKey: "author") as! String
            let userIDText = snapshot.value!.object(forKey: "uid") as! String
            }) { (error) in
                print(error.localizedDescription)
            }
 

Как я могу использовать «uid», полученный из приведенного выше запроса, чтобы выполнить последовательный запрос для извлечения «profilePicURL», используя значение «uid» в «users». Конечная цель — отобразить profilePic, хранящийся помимо записи, в tableview.

Спасибо вам за любую оказанную помощь.

Ответ №1:

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {


    let cell = tableView.dequeueReusableCell(withIdentifier: "HomeCell", for: indexPath) as! HomeTableViewCell

    cell.author.text = String(self.author[(indexPath as NSIndexPath).row])    
    let userIDText = String(self.userID[(indexPath as NSIndexPath).row])

    ref.child("users").child(userIDText).observeSingleEvent(of: .value, with: { (snapshot) in
        print("snaphot is (snapshot)")
        let imageLink = snapshot.value?["profileImageUrl"] as! String
        self.storageRef = FIRStorage.storage().reference(forURL: imageLink)

        cell.profilePic.loadImageUsingCacheWithUrlString(urlString: imageLink)

    }) { (error) in
        print(error.localizedDescription)
    }
    return cell      
}
 

Я использую следующее расширение для UIImageView для загрузки изображения с использованием URL-адреса, и это сработало!!

  let imageCache = NSCache<AnyObject, AnyObject>()

        extension UIImageView {

            func loadImageUsingCacheWithUrlString(urlString: String) {

            self.image = nil

            //check cache for image first
            if let cachedImage = imageCache.object(forKey: urlString) as? UIImage {
                self.image = cachedImage
                return
            }

            //otherwise fire off a new download
            let url = NSURL(string: urlString)
            URLSession.shared.dataTask(with: url! as URL, completionHandler: { (data, response, error) in

                //download hit an error so lets return out
                if error != nil {
                    print(error)
                    return
                }

                DispatchQueue.main.async(execute: {

                    if let downloadedImage = UIImage(data: data!) {
                        imageCache.setObject(downloadedImage, forKey: urlString)

                        self.image = downloadedImage
                    }
                })

            }).resume()
        }

    }
 

Ответ №2:

Лучшая идея — хранить разных пользователей в массиве пользователей, в котором User является структурой.

 struct User {
   var name: String = ""
   var id: String = ""
}
 

Затем в вашем ViewController вы загружаете содержимое из своей Firebase и создаете модели своей пользовательской структуры.

 let users: [User] = []

yourFireBaseQueryFunc() {
    ...
    postRef.observe(.childAdded, with: { (snapshot) in

         for item in snapshot {

              let name = snapshot.value!.object(forKey: "author") as! String
              let id = snapshot.value!.object(forKey: "uid") as! String
              let user = User(name: name, id: id)
              users.append(user)
         }
 

Затем, например, в a tableView вы берете indexPath и одну модель из своего массива моделей и вызываете функцию, чтобы получить ссылку на изображение из вашей Firebase:

 cellForRowAtIndexPath... {
    let user = users[indexPath.row]
    let image = getImage(user.id)
    let imgURL = NSURL(string: post.picture)
    cell.yourImageView.sd_setImageWithURL(imgURL)
}
 

А затем запросить изображение:

 func getImage(userID: String) -> String {

    var imageLink: String = ""

    let ref = firebase.child("users").child(userID)
    ref.observeEventType(.Value, withBlock: { snapshot in

        if snapshot.exists() {
            imageLink = snapshot.value!.valueForKey("profilePicURL") as! String
        }

    })

    return imageLink
}
 

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

1. Привет, Дэвид, спасибо за ваш быстрый ответ. Однако ваш ответ на самом деле не решает мою проблему.

2. Я использовал другой метод, используя кеш для загрузки изображений.