2017-03-13 3 views
1

내 뷰 컨트롤러 중 하나에서 Firebase에서 가져온 이미지를 표시하는 컬렉션보기가 있습니다. FeedViewController - 컨트롤러에서 viewDidLoad 이미지를 가져오고 fetchPosts 기능으로 이미지를 가져옵니다.하나의 호출에서 Firebase 데이터를 두 번 가져 오는 중

override func viewDidLoad() { 
    super.viewDidLoad() 

    posts.removeAll() 
    following.removeAll() 
    fetchPosts() 
} 

내가 몇 가지 "쇼"가 모두가 예상대로, 공급 부하를 잘 작동, FeedViewController에 segues : - 그렇지 않으면 두 번 나타납니다이이 일을하는 좋은 방법)이 아닌 경우 알려주세요 - 모든 이미지가 한 번 나타납니다. 그러나 사용자가 업로드 할 이미지를 선택하고 이미지가 가져와 져서 CV에 두 번 나타나게 한 다음 하나의 세그먼트가 생깁니다. SEGUE는 여기에 업로드 기능에 호출됩니다

func uploadToFirebase() { 
    AppDelegate.instance().showActivityIndicator() 

    let uid = FIRAuth.auth()!.currentUser!.uid 
    let ref = FIRDatabase.database().reference() 
    let storage = FIRStorage.storage().reference(forURL: "gs://cloudcamerattt.appspot.com") 
    let key = ref.child("posts").childByAutoId().key 
    let imageRef = storage.child("posts").child(uid).child("\(key).jpg") 
    let data = UIImageJPEGRepresentation(self.previewImage.image!, 0.6) 
    let uploadTask = imageRef.put(data!, metadata: nil) { (metadata, error) in 
     if error != nil { 
      print(error!.localizedDescription) 
      AppDelegate.instance().dismissActivityIndicator() 
      return 
     } 
     imageRef.downloadURL(completion: { (url, error) in 

      if let url = url { 
       let feed = ["userID" : uid, 
          "pathToImage" : url.absoluteString, 
          "likes" : 0, 
          "author" : FIRAuth.auth()!.currentUser!.displayName!, 
          "postID" : key] as [String : Any] 

       let postFeed = ["\(key)" : feed] 
       ref.child("posts").updateChildValues(postFeed) 
       AppDelegate.instance().dismissActivityIndicator() 

       self.performSegue(withIdentifier: "showFeed", sender: nil) 
      } 
     }) 
    } 
    uploadTask.resume() 
} 

그것은 SEGUE이 (내가 틀렸다면 나를 다시 수정) 그 함수 내에서 올바른 위치에있는 것처럼 보이지만, 사용자가 선택할 때 내가 말했듯 이미지를 선택하고 게시 버튼을 두드리면 위의 기능이 호출되어 피드 제어기로 되돌아 가고 게시자가 게시 한 이미지와 현재 피드에있는 다른 모든 이미지가 두 번 (때로는 세 번) 표시됩니다. 왜 이런 일이 일어나고 있는지 모르겠습니다. 피드에서 내비게이션으로 이동하여 다른 섹 그를 통해 피드로 돌아 오면 이미지가 제대로 표시됩니다. 즉 모든 이미지는 한 번만 표시됩니다. 다른 segues이 잘 작동하기 때문에 문제가 segues에없는, 또는 방법으로 FeedViewController 핸들 CV를 (이 비효율적 일 수도 있지만) 채우는 &를 가져 오는 것처럼

그래서, 나는 생각합니다. 그것은 업로드 기능에 있어야합니다. 그리고 내가 말했듯이, 나는 그 기능 내에서 segue를 부를 논리적 인 장소를 더 이상 볼 수 없다. 아무도 내가 여기에서 놓친 것을 볼 수 있습니까?

편집 : 내 fetchPosts() 기능 :

func fetchPosts() { 

    var posts = [Post]() 

    let ref = FIRDatabase.database().reference() 
    ref.child("users").queryOrderedByKey().observe(.value, with: { snapshot in 

     let users = snapshot.value as! [String : AnyObject] 

     for (_, value) in users { 
      // get uid as string 
      if let uid = value["uid"] as? String { 
       // check to make sure uids match 
       if uid == FIRAuth.auth()?.currentUser?.uid { 
        // check for followers 
        if let followingUsers = value["following"] as? [String : String] { 
         // loop through those and add them to "following" array 
         for (_, user) in followingUsers { 
          self.following.append(user) 
         } 
        } 
        // add current user to that array also so you can see your own posts 
        self.following.append(FIRAuth.auth()!.currentUser!.uid) 

        ref.child("posts").queryOrderedByKey().observe(.value, with: { (snap) in 

         let postsSnap = snap.value as! [String : AnyObject] 

         for (_, post) in postsSnap { 
          if let userID = post["userID"] as? String { 
           for each in self.following { 
            if each == userID { 
             // here are the posts that the user should see (his own and his following) 
             let posst = Post() 
             if let author = post["author"] as? String, let likes = post["likes"] as? Int, let pathToImage = post["pathToImage"] as? String, let postID = post["postID"] as? String { 

              posst.author = author 
              posst.likes = likes 
              posst.pathToImage = pathToImage 
              posst.postID = postID 
              posst.userID = userID 
              if let people = post["peopleWhoLike"] as? [String : AnyObject] { 
               for (_, person) in people { 
                posst.peopleWhoLike.append(person as! String) 
               } 
              } 
              posts.append(posst) 
             } 
            } 
           } 
           self.collectionView.reloadData() 
          } 
         } 
        }) 
        ref.removeAllObservers() 
       } 
      } 
     } 
    }) 
} 
+0

fetchPosts() 메소드를 보여줄 수 있습니까? 너의 질문에 넣어 줘. –

+0

@PieterLebens가 방금 추가했습니다. 문제는 업로드 컨트롤러에서 분리했을 때만 발생하지만 이미지가 가져오고 다른 컨트롤러에서 올 때 완벽하게로드되므로 문제가 업로드 기능 내에 있어야한다고 생각한 이유입니다. – KingTim

+0

'observe' 대신에'.observeSingleEvent'를 포스트 레퍼런스에 사용해보십시오. 아무 것도 바뀌면 어쨌든 리스너를 제거하는 것 같습니다. –

답변

2

당신이 변화에 대한 모니터링을 계속합니다 .observe를 사용합니다. 당신은 removeAllObservers을 사용 했으므로 데이터를 한 번만 필요하다고 가정했습니다. 이 경우 데이터를 한 번만 가져 오므로 .observeSingleEvent을 사용하는 것이 더 좋습니다.

내가 생각하는 바는이 코드가 실행되는 것을 보지 않고도 알 수 없다. Firebase은 비동기이기 때문에 코드는 실행을 계속하고 Firebase 명령이 완료되기를 기다리지 않습니다. updateChildValues가 실제로 완료되기 전에 피드에 연결하고 있다고 생각합니다. FeedViewController에 도착하면 컬렉션을 비우고 데이터를로드합니다. 데이터로드가 시작되고로드되는 동안 게시물이 추가됩니다. .value을 다시 트리거 한 이유는 데이터베이스에서 변경되어 여러 번 실행되기 때문입니다. 또한 viewDidLoad에서 컬렉션을 지우기 만하면 중복 게시물이 컬렉션에 추가됩니다.

.observe (당신은 내가 생각하는 주요 큐에 그것을 할 거라고하지만)을,이를 방지 observeSingleEvent 또는 대신 viewDidLoadremoveAll()를 사용 .observe 교체, 내부를 사용합니다.

+0

답변과 설명에 너무 감사드립니다! CV는 모든 중복 된 사진을로드하는 피드 컨트롤러로 다시 돌아가고 나서 몇 초 후에 지연이 생기기 때문에 그 일은 일어난 것처럼 들립니다. – KingTim

관련 문제