2017-09-19 1 views
0

Firebase에서 사용자 "게시물"(이미지 및 설명)을로드하려고합니다. 처음에는 모든 것이 잘 작동하는 것처럼 보였고 viewController에 3 개의 게시물을 보았습니다.하지만 Firebase에 새로운 이미지를 업로드하면 사용자가 모든 게시물의 양을 늘린 다음 앱이 4 개가 아닌 8 개의 게시물을로드합니다. 왜 이런 일이 일어나는 걸까요?Swift Firebase가 이미지를 너무 많이로드합니다.

여기 내 스냅 샷

Snap (qUJAq6aeNGYUeSsl9RmzldNpTME3) { 
"508D22DE-E865-460E-A011-A9170E0AB6A8" =  { 
    description = n; 
    downloadURL = "https://firebasestorage.googleapis.com/v0/b/findit-2f6eb.appspot.com/o/images%2F1A18AFAD-815C-417C-8C7A-226343FD0256.jpg?alt=media&token=46a6c929-a5ec-49e4-b6ca-aca896618fe0"; 
}; 
"D8434D58-1193-421D-8DFE-982983CB20D4" =  { 
    description = Maaa; 
    downloadURL = "https://firebasestorage.googleapis.com/v0/b/findit-2f6eb.appspot.com/o/images%2F059C91E8-95A8-44C6-9779-F678E2B9E033.jpg?alt=media&token=46ff5654-abec-49dc-bbb8-afae0eb6f1bd"; 
}; 
"F0E47F44-AE22-4D80-B173-E2168CB20B94" =  { 
    description = 7; 
    downloadURL = "https://firebasestorage.googleapis.com/v0/b/findit-2f6eb.appspot.com/o/images%2F1EA82DCA-FFE2-4B79-931C-28B66C7729AB.jpg?alt=media&token=8eaa2e02-5af8-4b43-adf2-2ac9214f902e"; 
}; 
} 

MyPostsTableViewController의

import UIKit 

import Firebase 



    class MyPostsTableViewController: UITableViewController { 
let user = Userr() 
var downloadURL = "" 



var desCription = "" 
var allPosts = [String]() 
let currUser = Auth.auth().currentUser?.uid 

override func viewDidLoad() { 
    super.viewDidLoad() 



    let ref = Database.database().reference().child("posts").child(currUser!) 
    ref.observe(.value, with: { (snapshot) in 

     print(snapshot) 

     let dictionary = snapshot.value as! [String: Any] 
     var keys = Array(dictionary.keys) 
     self.allPosts = keys 

     for index in 0...(keys.count - 1) { 
      self.allPosts.removeAll() 
      self.user.descriptions.removeAll() 
      self.user.downloadUrls.removeAll() 
     ref.child(keys[index]).child("description").observe(.value, with: { (snapshot) in 
      ref.child(keys[index]).child("downloadURL").observe(.value, with: { (snapshot2) in 
       self.user.descriptions.append(snapshot.value as! String) 
       self.user.downloadUrls.append(snapshot2.value as! String) 

       self.tableView.reloadData() 

      }) 
     }) 


     } 

    }) 


} 




override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    // #warning Incomplete implementation, return the number of rows 



     return user.descriptions.count 

} 


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



    // print("downloadUrls Count \(user.downloadUrls.count)") 


    cell.descriptionLabel.text = user.descriptions[indexPath.row] 

    let profileImageURL = user.downloadUrls[indexPath.row] 

    cell.imageVieeew.contentMode = .scaleAspectFit 

    cell.imageVieeew.loadImageUsingCacheWithUrlString(profileImageURL) 



    return cell 

} 



} 

PostViewController

import UIKit 
    import Firebase 


class PostViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate { 

let user = Userr() 

@IBOutlet var textField: UITextField! 
@IBAction func postToServer(_ sender: Any) { 

     self.user.allow = false 
    // successfully authenticated user 
    if imageViw.image != nil && textField.text != ""{ 

     let imageName = NSUUID().uuidString 
     let postName = NSUUID().uuidString 
     let imagesFolder = Storage.storage().reference().child("images") 

     if let imageData = UIImageJPEGRepresentation(imageViw.image!, 0.2){ 
      imagesFolder.child("\(imageName).jpg").putData(imageData, metadata: nil, completion:{ 
       (metadata, error) in 

       if let error = error{ 
        self.presentAlert(alert: error.localizedDescription) 
       } else{ 
        if let downloadURL = metadata?.downloadURL()?.absoluteString { 

         let currUser = Auth.auth().currentUser?.uid 
         let ref = Database.database().reference().child("posts").child(currUser!).child(postName) 
         ref.child("downloadURL").setValue(downloadURL) 
         ref.child("description").setValue(self.textField.text!) 

        } 
       } 

      }) 


      } 

    } 
    else { 
     // we're missing something 
     presentAlert(alert: "You mus provide an image and a message for your post.") 
    } 


} 
+1

firebase만이 새 하위를 제공하는'Child added observer'를 추가하십시오. 'Type value observer'를 추가하면 모든 자식을 반환합니다. –

답변

3

새 게시물이 추가 될 때마다 얻을 수있는 다른 방법을 살펴보십시오은, 코드, 실행 다른 수신기를 부착 . 경로의 .value이 변경되었으므로 원래의 .observe 청취자가 변경 사항을 트리거하므로 각 어린이에게 개별적으로 청취 할 필요가 없습니다. 대신 childSnapshots을 반복하고 필요에 따라 데이터를 추가하십시오. 데이터와 코드를 테스트하지 않았으므로이 코드를 조정해야 할 수도 있습니다.

let ref = Database.database().reference().child("posts").child(currUser!) 
    ref.observe(.value, with: { (snapshot) in 

     print(snapshot) 
     self.allPosts.removeAll() 
     self.user.descriptions.removeAll() 
     self.user.downloadUrls.removeAll() 

     guard let snapshots = snapshot.children.allObjects as? [DataSnapshot] else { return } 
     for snap in snapshots { 
      self.user.descriptions.append(snap.childSnapshot(forPath: "description").value as! String) 
      self.user.downloadUrls.append(snap.childSnapshot(forPath: "downloadURL").value as! String) 
     } 

     self.tableView.reloadData() 
    }) 
+0

대단히 감사합니다! –

+0

@JenPerson이 지속 가능한 디자인입니까? 1,000 개의 게시물이있는 경우 클라이언트 측 장치는 1,000 개의 게시물을 모두 다시 다운로드해야합니다. 이것은 작은 응용 프로그램에서는 잘 작동하지만 많은 양의 데이터가있는 응용 프로그램에서는 좋은 아이디어가 아닙니다. – DoesData

+0

우려 사항이 지속 가능성이라면 페이징 또는 무한 스크롤을 사용하는 데이터 모델을 만들 수 있습니다.이 모델은 한 번에 몇 가지 항목을 쿼리합니다. 'childAdded','childRemoved','childChanged'를 가진 데이터 모델을 사용하는 것도 옵션입니다. –

0

문제는 여기 ref.observe(.value, with: { (snapshot) in

입니다 .value은 모든 데이터를 반환합니다. 따라서 중복 된 데이터를 얻습니다. 이 번호를 .childAdded으로 변경하면 새로운 소식 정보 만 앱에 반환됩니다.

또한 어느 시점에서 그 옵저버를 제거하려고 할 것입니다. 앱이 어떻게 작동하는지 모르겠으므로 그 시점은 언제인지 모르겠지만 마음에 두어야 할 부분입니다.

ref.removeAllObservers()을 사용하십시오. 당신은 당신이 첨부했습니다 각 청취자에 대해 한 번 설명과 downloadUrls을 추가 할 수 있습니다 있도록

데이터 here

관련 문제