2016-06-26 2 views
1

Я довольно новичок в firebase, поэтому мой недостаток кода - это не просто попытка просто попробовать «Я действительно не знаю, с чего начать».Firebase запрос только для возврата новых сообщений?

Я стараюсь показывать только сообщения, которые находятся в течение 10 минут «старые» или менее. Я собираюсь запустить таймер в своем приложении, чтобы отправлять запрос каждую секунду (при условии, что это не вызывает слишком много проблемы?), Чтобы проверить, не текущие сообщения не превышают отметку в 10 минут, и если они, запрос просто не должен их возвращать.

У меня он настроен там, где когда пользователь делает сообщение, создается временная метка.

Установка является:

Posts 
    02983094jfksdflkaj3l 
     timestamp: 23478923019 

Я предполагаю, что мне нужно orderByValue? сортировать сообщения по метке времени, а затем возвращать ее с некоторым пределом, но я не уверен, как отобразить все это.

Точка в правильном направлении была бы принята с пониманием.

Заранее благодарен!

Редактировать: Я больше не получаю сообщений, появляющихся в коллекции ... и независимо от того, сколько сообщений у меня есть, которые должны удовлетворять запросам менее 10 минут, возвращается только один.

Как я покажу ниже, я не получаю возврат .value на привязку ..., который должен вернуть значение временной метки, которое я покажу в привязке timestamp, нет?

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 

} 

Тогда для запроса 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 предоставит вам все должности, у которых есть значение, которое вы назначили или больше.

Есть несколько лучших способов справиться с этим, что немного более активно, но это должно быть хорошим началом, у New Firebase есть отличные документы и примеры. Ознакомьтесь с разделом «База данных»/«Получить данные» для получения дополнительной информации о сортировке/фильтрации.

Надеюсь, это поможет вам начать работу, сообщите мне, если у вас есть вопросы.

+0

грн. Этот запрос будет работать некорректно, так как он:. Добавлена ​​добавленная запись будет захватывать один дочерний узел за раз, поэтому в снимке будет только один, что отрицает итерацию над снимком для дополнительных сообщений. Он также опустят массив после каждого вызова, чтобы вы получили одно сообщение. Кроме того, это может привести к тому, что таблица начнет мигать, как если бы было 1000 сообщений, она будет быстро обновлять tableView 1000 раз подряд. Кроме того, если x = 9am, наблюдатели добавляются для всех сообщений: от 8:50 до 9 утра. Затем, если он снова запустится в 9:10, он добавит дополнительных наблюдателей для всего: от 9:10 до 9 поверх сообщений с 8:50 до 9 утра. – Jay

+0

так что вы считаете лучшим? observeSingleEventOfType (.value)? – JustinM

+0

Да, это хороший старт, если OP идет с таймером. Но если это так, то это действительно добавляет много накладных расходов на приложение и вроде бы побеждает цель Firebase. Кроме того, если этот таймер срабатывает каждую секунду, он потенциально может нажимать на значительное количество данных и запускает проблему «callback hell» в том, что данные возвращаются до обработки последних данных. Мыслительный процесс, лежащий в основе потока данных и того, как он представлен, вероятно, должен быть повторно посещен. – Jay

Смежные вопросы