Android Firebase query OR operator [duplicate]

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

  • обрабатывать асинхронные HTTP-вызовы;
  • Подождать ответа от каждого вызова API;
  • Использовать шаблон promise ;
  • Используйте шаблон Promise.All для объединения нескольких HTTP-вызовов;

Этот рабочий пример является автономным. Он будет определять простой объект запроса, который использует объект window XMLHttpRequest для совершения вызовов. Он будет определять простую функцию, чтобы дождаться завершения кучи обещаний.

Контекст. В этом примере запрашивается конечная точка Spotify Web API для поиска объектов playlist для заданного набора строк запроса:

[
 "search?type=playlist&q=%22doom%20metal%22",
 "search?type=playlist&q=Adele"
]

Для каждого элемента новый Promise запустит блок - ExecutionBlock, проанализирует результат, заплатит новый набор обещаний на основе массива результатов, который представляет собой список объектов Spotify user и выполняет новый HTTP-вызов в ExecutionProfileBlock асинхронно.

Затем вы можете увидеть вложенную структуру Promise, которая позволяет вам генерировать множественные и полностью асинхронные вложенные HTTP-вызовы и присоединять результаты к каждому подмножеству вызовов через Promise.all.

NOTE Recent Spotify search API-интерфейсам потребуется указать токен доступа в заголовках запроса:

-H "Authorization: Bearer {your access token}" 

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

var spotifyAccessToken = "YourSpotifyAccessToken";
var console = {
    log: function(s) {
        document.getElementById("console").innerHTML += s + "
" } } // Simple XMLHttpRequest // based on https://davidwalsh.name/xmlhttprequest SimpleRequest = { call: function(what, response) { var request; if (window.XMLHttpRequest) { // Mozilla, Safari, ... request = new XMLHttpRequest(); } else if (window.ActiveXObject) { // Internet Explorer try { request = new ActiveXObject('Msxml2.XMLHTTP'); } catch (e) { try { request = new ActiveXObject('Microsoft.XMLHTTP'); } catch (e) {} } } // State changes request.onreadystatechange = function() { if (request.readyState === 4) { // Done if (request.status === 200) { // Complete response(request.responseText) } else response(); } } request.open('GET', what, true); request.setRequestHeader("Authorization", "Bearer " + spotifyAccessToken); request.send(null); } } //PromiseAll var promiseAll = function(items, block, done, fail) { var self = this; var promises = [], index = 0; items.forEach(function(item) { promises.push(function(item, i) { return new Promise(function(resolve, reject) { if (block) { block.apply(this, [item, index, resolve, reject]); } }); }(item, ++index)) }); Promise.all(promises).then(function AcceptHandler(results) { if (done) done(results); }, function ErrorHandler(error) { if (fail) fail(error); }); }; //promiseAll // LP: deferred execution block var ExecutionBlock = function(item, index, resolve, reject) { var url = "https://api.spotify.com/v1/" url += item; console.log( url ) SimpleRequest.call(url, function(result) { if (result) { var profileUrls = JSON.parse(result).playlists.items.map(function(item, index) { return item.owner.href; }) resolve(profileUrls); } else { reject(new Error("call error")); } }) } arr = [ "search?type=playlist&q=%22doom%20metal%22", "search?type=playlist&q=Adele" ] promiseAll(arr, function(item, index, resolve, reject) { console.log("Making request [" + index + "]") ExecutionBlock(item, index, resolve, reject); }, function(results) { // Aggregated results console.log("All profiles received " + results.length); //console.log(JSON.stringify(results[0], null, 2)); ///// promiseall again var ExecutionProfileBlock = function(item, index, resolve, reject) { SimpleRequest.call(item, function(result) { if (result) { var obj = JSON.parse(result); resolve({ name: obj.display_name, followers: obj.followers.total, url: obj.href }); } //result }) } //ExecutionProfileBlock promiseAll(results[0], function(item, index, resolve, reject) { //console.log("Making request [" + index + "] " + item) ExecutionProfileBlock(item, index, resolve, reject); }, function(results) { // aggregated results console.log("All response received " + results.length); console.log(JSON.stringify(results, null, 2)); } , function(error) { // Error console.log(error); }) ///// }, function(error) { // Error console.log(error); });

Я подробно рассмотрел это решение здесь .

1
задан Ruben 19 January 2015 в 22:52
поделиться

1 ответ

В настоящее время Firebase может запрашивать только одно дочернее свойство. Поэтому, если вы хотите запросить несколько свойств, вам придется объединить их в один:

Messages
  -DFHJ3498ua
    from: Tony
    to: Bob
    from_to: Tony_Bob
    message: "Hello Bob, this is Tony"
  -DFHJ3598uz
    from: Bob
    to: Tony
    from_to: Bob_Tony
    message: "Hello Tony, What can I do for you?"
  -EFHJ3498ua
    from: Tony
    to: Bob
    from_to: Tony_Bob
    message: "Can you help me with this Firebase query?"

Затем вы можете запросить сообщения от Боба до Тони, используя:

var ref = new Firebase('https://your.firebaseio.com/Messages');
var query = ref.orderByChild('from_to').equalTo('Bob_Tony');
query.on('value', function(snapshot) {
  console.log(snapshot.val()); // all messages from Bob to Tony
});

В чатовом приложении вам может потребоваться на самом деле использовать пару отправителя-получателя в качестве ключа:

Messages
  from_Bob_to_Tony
    -DFHJ3598uz
      from: Bob
      to: Tony
      message: "Hello Tony, What can I do for you?"
  from_Tony_to_Bob
    -DFHJ3498ua
      from: Tony
      to: Bob
      message: "Hello Bob, this is Tony"
    -EFHJ3498ua
      from: Tony
      to: Bob
      message: "Can you help me with this Firebase query?"

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

var ref = new Firebase('https://your.firebaseio.com/Messages');
var query = ref.child('from_Bob_to_Tony');
query.on('value', function(snapshot) {
  console.log(snapshot.val()); // all messages from Bob to Tony
});
6
ответ дан Frank van Puffelen 22 August 2018 в 13:42
поделиться
  • 1
    Спасибо :) Быстрые вопросы: если я получаю пару отправителя-получателя, мне нужно будет сделать 2 запроса (от Т до В и В до Т), объединить их и отсортировать по времени. Разве я не должен организовывать его по комнатам людей? – Ruben 20 January 2015 в 02:03
  • 2
    Также, если я делаю систему комнаты, должен ли я иметь коллекцию комнаты, где каждый элемент имеет длинный массив сообщений, или я должен создать коллекцию сообщений, которая ссылается на комнату? Какая лучшая схема? – Ruben 20 January 2015 в 02:57
  • 3
    Ваш вопрос сказал «сообщения, отправленные Тони и полученные Бобом», так вот что я смоделировал в своем ответе. Если вам нужны сообщения между Тони и Боб, вы можете моделировать это, например. заказывая имя перед тем, как положить их в ключ. Таким образом, такой ключ, как «messages_between_Bob_and_Tony». – Frank van Puffelen 20 January 2015 в 03:19
  • 4
    Если вы хотите моделировать чаты, моделируйте чаты. Если вы хотите, чтобы комнаты между участниками были постоянными (поэтому, когда одни и те же люди начинают говорить снова, они видят свои предыдущие сообщения), это будет проще всего, если вы моделируете на основе имен пользователей / идентификаторов. Но все это невероятно широко, и невозможно определить «лучший». ответьте за вас, не перебирая все ваши прецеденты, для которых StackOverflow не является форумом. Просто начните с того, что кажется правильным и адаптируйтесь к новым идеям. Или посмотрите firebase.com/tutorial/#session/ztbgh3woflv или github.com/firebase/firechat – Frank van Puffelen 20 January 2015 в 03:22
Другие вопросы по тегам:

Похожие вопросы: