2016-06-26 3 views
1

나는 코드의 부족이 단지 "나는 어디에서 시작 해야할지 정말로 모른다"더 많은 것을 시도하지 않는 것이 아니기 때문에 나는 새로운 firebase를 가지고 있습니다.새 게시물 만 반환하는 Firebase 쿼리?

"오래된"이하의 게시물 만 표시하려고합니다. 매 초마다 쿼리를 보내려면 타이머를 실행해야합니다 (문제가 너무 많이 발생하지 않는다고 가정 할 때?) 현재 게시물이 10 분 넘지 않았는지 확인하고 if 그것들은 질의가 단지 그것들을 리턴해서는 안된다.

나는 사용자가 타임 스탬프가 작성된 게시물을 만들 때 설정해야합니다.

셋업은 다음과 같습니다

Posts 
    02983094jfksdflkaj3l 
     timestamp: 23478923019 

은 내가 orderByValue 할 필요가 있으리라 믿고있어? 게시물을 타임 스탬프별로 정렬 한 다음 일종의 제한으로 반환하지만 모든 것을 매핑하는 방법을 모르겠습니다.

오른쪽 방향의 한 점이 크게 인정 될 것입니다.

미리 감사드립니다.

편집 : 더 이상 collectionview ...에 게시물이 표시되지 않으며 10 분 미만의 쿼리를 충족해야하는 게시물이 몇 개라도 상관없이 하나만 반환됩니다.

아래와 같이 스냅 샷에서 .value 리턴을 얻지 못했습니다 ... 타임 스탬프 스냅 샷에 표시된 타임 스탬프 값을 반환해야합니까?

override func viewWillAppear(animated: Bool) { 
    let cutoff = UInt64(1000 * floor(NSDate().timeIntervalSince1970) - 10*60*1000); 
    let cutoffFloat = Float(cutoff) // <-- woudnlt take a UInt64 as an AnyObject. I assume its ok to just do this? 


    DataService.ds.REF_POSTS.queryOrderedByChild("timestamp").queryStartingAtValue(cutoffFloat).observeSingleEventOfType(.ChildAdded) { (snapshot: FIRDataSnapshot) in 
     print("child added") // <------- isn't ever getting called 
     self.Posts = [] 
     if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot] { 

      for snap in snapshots { 

      print("timestamp snap: \(snap)") // <---- returns timestamp snap: Snap (timestamp) 23904819242 

         if let postDict = snap.value as? Dictionary<String, AnyObject> { 

        print(snap.value)// <----- Returns nothing 
        let key = snap.key 
        let post = Post(postKey: key, dictionary: postDict) 
        self.Posts.append(post) 

       } 
      } 
     } 

     self.collectionView.reloadData() 

}

그것이 내가 컬렉션보기 채울 전에 사용하던 내 코드 도움이다 그러나 여기 있었다면 나도 몰라 :

여기
DataService.ds.REF_POSTS.observeEventType(.Value) { (snapshot: FIRDataSnapshot) in 

     self.Posts = [] 
     if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot] { 

      for snap in snapshots { 

       print(snap) 

       if let postDict = snap.value as? Dictionary<String, AnyObject> { 
        let key = snap.key 
        let post = Post(postKey: key, dictionary: postDict) 
        self.Posts.append(post) 
       } 
      } 
     } 

     print("got here") 
     self.collectionView.reloadData() 


    } 
+0

타이머가 필요하지 않을 수 있으며 지난 10 분 동안 1024 개의 게시물이있는 상황을 고려할 수 있습니다. 해당 게시물 중 몇 개를 고객에게 제공해야합니까? 내 생각 엔 당신이 모든 것에 관심을 가질 수는 있지만 한 번에 20 개 (예를 들어) 또는 가장 최근 20 개를보고 싶을뿐입니다. Firebase는 비동기로 기억하십시오 - 노드 노드에 옵저버를 추가하면됩니다. 자동으로 새 게시물에 대한 알림을 받게됩니다. * 항상 최신 게시물이 표시됩니다. 폴링은 Firebase가 작업을 수행함으로써 완전히 제거 될 수 있습니다. – Jay

+0

@Jay 친구 그룹에서 한 번에 9 개의 게시물을 한 번에 한 사용자에게 표시 할 수 있으며, 구현하려고하는 기능에는 10 분의 비트가 중요합니다. 제한된 양의 "쇼 시간"이있는 게시물과 상호 작용하는 앱의 요점으로 표시되는 게시물이 없으면 괜찮습니다. 사용자의 친구의 게시물을 9 개로 제한하면 홍수와 관련된 문제가 없어야합니다. 나는 또한 이것이 최선의 방법이라고 가정하고 있습니다. 이런 식으로 가면서 눈부신 문제가 보이지 않습니까? – Noowoo

답변

3

타이머를 실행하고 10 초마다 다른 쿼리를 보내는 것은 실시간 데이터베이스의 끔찍한 사용입니다. 대신 10 분 전부터 모든 게시물을 요청한 쿼리를 실행하고 해당 쿼리를 계속 활성화하십시오. @ JustinM의 코드에서 대출

:

let ref = FIRDatabase.database().reference 
let cutoff = UInt64(1000 * floor(NSDate().timeIntervalSince1970) - 10*60*1000);  
ref.child("post") 
    .queryOrderedByChild("timestamp") 
    .queryStartingAtValue(cutoff) 
    .observeSingleEventOfType(.ChildAdded, withBlock: { snapshot in 
     let post = Post(title: snapshot["title"], timestamp: snapshot["timestamp"]) 
     self.postsArray.append(post) 
    } 

    self.tableView.reloadData() 

    // start a timer that removes expired items from postsArray 
    NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "removeExpiredItems", userInfo: nil, repeats: true) 
}) 

그런 다음 클라이언트 쪽은 타이머를 실행하고 그들이 "만료"로 게시물을 삭제.

func removeExpiredItems() { 
    let cutoff = UInt64(1000 * floor(NSDate().timeIntervalSince1970) - 10*60*1000) 
    while (self.postsArray.count > 0 && self.postsArray[0].timestamp < cutoff) { 
     // remove first item, because it expired 
     self.postsArray.removeAtIndex(0) 
    } 
    self.tableView.reloadData() 
} 
+0

지금까지 도움을 주셔서 감사합니다. 나는 원래 게시물의 편집으로 추가 한이 코드를 구현하려고하는 몇 가지 문제에 직면하고있다. 좀 봐 주시겠습니까? – Noowoo

+0

프랭크에게 감사드립니다. 나는 코멘트 이외에 이것을 쓸 시간이 없었다. 이것은 분명히 정답입니다. – Jay

2

당신이 설정 얼마나입니다 타이머 실행 :

NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector "updateTime", userInfo: nil, repeats: true) 

} 
func updateTime() { 
    let currentTime = NSDate() 
    self.time = currentTime.description 

} 

다음 10 분간의 게시물에 대한 firebase를 쿼리하려면 :

let ref = FIRDatabase.database().reference 
//let x = currentTime - 10 minutes in equivalent time structure. For example, if by minutes, currentTime - 10. You put that in queryStartingAtValue. 
ref.child("post").queryOrderedByChild("timestamp").queryStartingAtValue("x").observeSingleEventOfType(.Value, withBlock: { snapshot in 
     self.postsArray.removeAll 
     for snap in snapshot.children { 
      let post = Post(title: snap["title"], timeStamp: snap["timestamp"]) 
      self.postsArray.append(post) 
     } 

     self.tableView.reloadData() 
    }) 

queryStartingAtValue는 사용자가 할당 한 값 이상인 모든 게시물을 제공합니다.

이 문제를 좀 더 잘 처리 할 수있는 방법이 있지만이 방법이 좋은 시작이 될 것입니다. 새로운 Firebase에는 좋은 문서와 예제가 있습니다. 정렬/필터링에 대한 자세한 내용은 데이터베이스/검색 데이터 섹션을 참조하십시오.

희망 사항을 알려주세요. 궁금한 점이 있으면 알려주세요.

+0

어. 이 쿼리는 그대로 작동하지 않습니다. 추가 된 .Child는 한 번에 하나의 하위 노드를 캡처하므로 추가 게시물에 대한 스냅 샷 반복을 무시하는 스냅 샷에 하나만 존재합니다. 또한 각 호출 후에 배열을 비 웁니다. 그러면 하나의 게시물로 끝납니다. 또한 1000 개의 게시물이있는 것처럼 표가 깜박이는 경우 tableView를 1000 번 빠르게 연속적으로 업데이트합니다. 또한 x = 9am 인 경우 모든 게시물에 대해 관찰자가 추가됩니다 (8:50 ~ 9am). 그런 다음 9시 10 분에 다시 실행되면 9시 10 분부터 9 시까 지 8시 50 분에서 9시 지점에 추가 관찰자가 추가됩니다. – Jay

+0

그래서 무엇이 최고라고 생각합니까? observeSingleEventOfType (.value)? – JustinM

+0

예, OP가 타이머와 함께 있으면 좋은 시작입니다. 그러나 그것이 사실이라면 앱에 많은 오버 헤드를 추가하고 Firebase의 목적을 깨뜨리는 것입니다. 또한 해당 타이머가 매초마다 실행되면 상당한 양의 데이터를 잠재적으로 밀어 낼 수 있으며 마지막 데이터가 처리되기 전에 데이터가 반환된다는 점에서 '콜백 지옥'문제가 발생합니다. 데이터 흐름의 사고 방식과 데이터 표시 방법은 아마도 다시 방문해야합니다. – Jay