2017-03-21 113 views
-1

我正在嘗試從我的數據庫中進行一次抓取以填充集合視圖,按照最新的順序從頂部到最舊。我嘗試使用snap.children.allObjects.reversed(),但我的應用程序在加載時崩潰。下面是完整的提取功能:嘗試使用.reversed()對Firebase進行排序時發生崩潰

func fetchPosts() { 

    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 { 

      if let uid = value["uid"] as? String { 

       if uid == FIRAuth.auth()?.currentUser?.uid { 

        if let followingUsers = value["following"] as? [String : String] { 

         for (_, user) in followingUsers { 
          self.following.append(user) 
         } 
        } 
        self.following.append(FIRAuth.auth()!.currentUser!.uid) 

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

         for postSnapshot in snap.children.allObjects.reversed() as! [FIRDataSnapshot] { 
          let value = postSnapshot.value as! [String : AnyObject] 

          if let userID = value["userID"] as? String { 
           for each in self.following { 
            if each == userID { 

             let posst = Post() 
             if let poster = value["poster"] as? String, let likes = value["likes"] as? Int, let pathToImage = value["pathToImage"] as? String, let postID = value["postID"] as? String { 

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

的錯誤是EXC_BAD_INSTRUCTION (code=EXC_1386_INVOP, subcode=0x0),從 'ReversedRandomAccessCollection < [任何]>'(又名 'ReversedRandomAccessCollection>')無關型 '[FIRDataSnapshot]' 警告演員總是失敗。

.reversed不是這樣的嗎?實際上,我的代碼沒有.reversed按從頂部最舊的順序到最底部的順序加載帖子。我怎樣才能切換它?

編輯:帖子的火力地堡片段:

"posts" : { 
"-KfWzWv8rP38bUreDupj" : { 
    "likes" : 1, 
    "pathToImage" : "https://firebasestorage.googleapis.com/v0/b/cloudcamerattt.appspot.com/o/posts%2F1JSgke8QqFds4CxF2Z4MhuzbRoW2%2F-KfWzWv8rP38bUreDupj.jpg?alt=media&token=fef86bea-1ae2-4e1e-82fa-6209bc281a5e", 
    "peopleWhoLike" : { 
    "-KfX29jTcwaQDpkdIVX8" : "yI6NokUl2mTa7Uah4SgtAiulTJH2", 
    "-KfXQJBRemZUCI2ieT94" : "MpnGvQj7ZOdz12zKD0bTeX1kp0B3" 
    }, 
    "postID" : "-KfWzWv8rP38bUreDupj", 
    "poster" : "Harry Potter", 
    "userID" : "1JSgke8QqFds4CxF2Z4MhuzbRoW2" 
}, 

編輯2:添加時間戳

新增var timestamp: Int!Post對象,然後將其添加到我的上傳功能:

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) 
    var Timestamp: TimeInterval { 
     return NSDate().timeIntervalSince1970 * 1000 
    } 

    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, 
          "poster" : FIRAuth.auth()!.currentUser!.displayName!, 
          "postID" : key, 
          "timestamp" : (0-Timestamp)] as [String : Any] 

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

       let feedController = self.storyboard?.instantiateViewController(withIdentifier: "feedVC") as! FeedViewController 
       feedController.navigationItem.setHidesBackButton(true, animated: false) 

       self.tabBarController?.selectedIndex = 0 
      } 
     }) 
    } 
    uploadTask.resume() 
} 

然後將其添加到我的提取中:

         let posst = Post() 
             if let poster = value["poster"] as? String, let likes = value["likes"] as? Int, let pathToImage = value["pathToImage"] as? String, let postID = value["postID"] as? String, let timestamp = value["timestamp"] as? Int { 

              posst.poster = poster 
              posst.likes = likes 
              posst.pathToImage = pathToImage 
              posst.postID = postID 
              posst.userID = userID 
              posst.timestamp = timestamp 

更新抓取功能(在崩潰Could not cast value of type 'FIRDataSnapshot' (0x10584eee8) to 'NSArray' (0x107b43dd8).結果):

func fetchPosts() { 

    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 { 

      if let uid = value["uid"] as? String { 

       if uid == FIRAuth.auth()?.currentUser?.uid { 

        if let followingUsers = value["following"] as? [String : String] { 

         for (_, user) in followingUsers { 
          self.following.append(user) 
         } 
        } 
        self.following.append(FIRAuth.auth()!.currentUser!.uid) 

        for child in snapshot.children.reversed() { 
         let snap = child as! [FIRDataSnapshot] 

        ref.child("posts").queryOrdered(byChild: "timestamp").observeSingleEvent(of: .value, with: { (snap) in 

          if let userID = value["userID"] as? String { 
           for each in self.following { 
            if each == userID { 

             let posst = Post() 
             if let poster = value["poster"] as? String, let likes = value["likes"] as? Int, let pathToImage = value["pathToImage"] as? String, let postID = value["postID"] as? String, let timestamp = value["timestamp"] as? Int { 

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

在您的問題中發佈Firebase結構的片段通常是一個好主意;作爲*文字*請,沒有圖像。您可以通過Firebase控制檯中的導出(右上角的三個點)功能將該JSON結構顯示爲文本。 – Jay

+0

@Jay抱歉,我現在正在添加一個片段 - 我在猜測「帖子」(這是抓取的內容來填充Feed)? – KingTim

回答

1

嘗試

for child in snapshot.children.reversed() { 
    let snap = child as! FIRDataSnapshot 
    print(snap) 
} 

你被哪個鍵會加載最舊到最新排序。如果你想顛倒順序,讓火力地堡做繁重,使用貼在這裏

In Firebase, how can I query the most recent 10 child nodes?

然後很容易做反向查詢的時間倒序排列的技術...

"posts" : { 
    "-KfWzWv8rP38bUreDupj" : { 
     "likes" : 1, 
     "pathToImage" : "https:/...", 
     "peopleWhoLike" : { 
     "-KfX29jTcwaQDpkdIVX8" : "yI6NokUl2mTa7Uah4SgtAiulTJH2", 
     "-KfXQJBRemZUCI2ieT94" : "MpnGvQj7ZOdz12zKD0bTeX1kp0B3" 
     }, 
     "postID" : "-KfWzWv8rP38bUreDupj", 
     "poster" : "Harry Potter", 
     "timestamp" : -1.46081635550362E12, //Just add this child 
     "userID" : "1JSgke8QqFds4CxF2Z4MhuzbRoW2" 
}, 

然後

ref.child("posts").queryOrdered(byChild: "timestamp").observe(... 

而且,可能不是因爲它的關鍵崗位以及需要重複的帖子ID作爲一個孩子。

+0

謝謝,我正在閱讀你的其他答案,並試圖添加一個時間戳。我編輯了我的帖子以顯示我正在嘗試的內容,但我的收藏視圖未加載,我想是因爲那裏的帖子已經沒有時間戳了? – KingTim

+0

@KingTim正確。如果您想讓Firebase進行排序,則需要在所有帖子中包含時間戳子節點。您可以使用代碼完成此操作,但Firebase在服務器級別執行排序並以正確順序爲您提供數據的方式會更快。 – Jay

+0

好酷,所以我走在正確的軌道上 - 但我不理解你的評論,我是否應該按照現在的方式添加時間戳?有沒有不同的方式讓Firebase進行訂購? – KingTim

0

你是對的,你需要在某個地方施放某些東西,因爲Swift只知道我們以任何一個數組開始。問題在於你在錯誤的地方投了錯誤的東西。在for循環的內部開始處演示postSnapshot

找出這種東西的方法是製作一個簡化的操場示例。你正在做的這相當於:

let arr : [Any] = [1,2,3] 
for i in arr.reversed() as! [Int] { // crash 
} 

我們知道在什麼例子,但是,是不是一些關於arr.reversed();它是i是一個Int。這很好:

let arr : [Any] = [1,2,3] 
for i in arr.reversed() { 
    if let i = i as? Int { 
     // now it is safe to use `i` 
    } 
} 

你的情況是平行的。在for循環開始時,您需要將postSnapshot投射到FIRDataSnapshot。現在你可以繼續了。

相關問題