iOS Firebase сортировка и ограничение — наблюдатель не вызываются

#ios #swift #firebase #firebase-realtime-database

#iOS #swift #firebase #firebase-база данных в реальном времени

Вопрос:

Это моя модель данных.

 project-foo
 -posts
   -KLs123412341234
     key: "-KLs123412341234"
     message: "free cupcakes"
     time: 1467675688163
   -...
     key: "..."
     message: "..."
     time: ...
  

Я бы хотел получать сообщения только за последние 15 минут.
Я вижу, что в моей консоли Firebase добавляются дочерние элементы, но проблема в том, что наблюдатель, похоже, не вызывается — "hello" не печатается.

Мое приложение для iOS имеет следующий код, который не вызывается:

 class ViewController: UIViewController {

    var ref: FIRDatabaseReference?

    override func viewDidLoad() {
        super.viewDidLoad()

        ref = FIRDatabase.database().reference()
        ref!.queryOrderedByChild("time")
            .queryStartingAtValue(startTime())
            .observeEventType(.ChildAdded, withBlock: { snapshot in
            print("hello")
        })

    }
}
  

В моем приложении для Android есть следующий код, который действительно вызывается:

 Query query = mDatabase.orderByChild("time").startAt((double)startTime());
query.addChildEventListener(new PostListener(this, mMap));

class PostListener implements ChildEventListener {
    public PostListener(Context context, GoogleMap map) {
        ...
    }

    @Override
    public void onChildAdded(DataSnapshot dataSnapshot, String s) {
        Log.i(TAG, "hello");
        ...
    }
}
  

Обновить:
Моя ошибка заключалась в том, что я не понял, что я инициализировал mDatabase (в версии для Android) с помощью path posts . Исправление состояло в том, чтобы просто инициализировать ref с FIRDatabase.database().referenceWithPath("posts") помощью вместо FIRDatabase.database().reference() .

Комментарии:

1. Как выглядит startTime() ?

2. Я тестировал, просто установив его равным нулю, и это не помогло.

3. Что такое ссылка ?…

Ответ №1:

Для структуры JSON,:-

 "posts" : {
  "autoID1" : {
    "key" : "autoID1",
    "timestamp" : 101
  },
  "autoID2" : {
    "key" : "autoID2",
    "timestamp" : 102
  },
  "autoID3" : {
    "key" : "autoID3",
    "timestamp" : 103
  },
  "autoID4" : {
    "key" : "autoID4",
    "timestamp" : 104
  },
  "autoID5" : {
    "key" : "autoID5",
    "timestamp" : 105
  },
  "autoID6" : {
    "key" : "autoID6",
    "timestamp" : 106
  },
  "autoID7" : {
    "key" : "autoID7",
    "timestamp" : 107
  }
}
  

Используйте этот код:-

   FIRDatabase.database().reference().child("posts").queryOrderedByChild( "timestamp").queryStartingAtValue(101).queryEndingAtValue(103).observeEvenType(.Value, with: { (snap) in
        if let snapDict = snap.value as? [String:AnyObject]{

            for each in snapDict{

                print(each.value)

            }
          }
        }, withCancel: {(err) in


    })
  

Убедитесь, что ваши правила безопасности позволяют пользователю извлекать posts значения

Использование .ChildAdded вызывается только тогда, когда дочерний узел добавляется к этому узлу базы данных. Использование .Value извлечет все данные, временная метка которых находится между этими значениями

Теперь, скорее всего, вы не можете получить значение метки FIRServerValue.timestamp() времени, поскольку это просто команда, отправленная на сервер firebase для добавления метки времени на этот конкретный узел.

Поэтому вместо этого используйте пользовательскую временную метку для хранения вашей временной метки, а для конечного значения просто добавьте 15 минут к этой временной метке.

Прочитайте эту манипуляцию с NSDate