Я пытаюсь обновить части WebView в своем приложении для Android с данными, которые я получаю от однорангового узла, подключенного через Firebase. Для этого было бы полезно выполнить блокирующие операции, которые возвратят необходимые данные. Например, реализация примера чата, который будет ждать, пока другой участник чата ничего не напишет перед возвратом push.setValue(). Возможно ли такое поведение с Firebase?Возможно ли синхронно загружать данные из Firebase?
ответ
На обычной JVM вы бы сделали это с помощью обычных примитивов синхронизации Java.
Например:
// create a java.util.concurrent.Semaphore with 0 initial permits
final Semaphore semaphore = new Semaphore(0);
// attach a value listener to a Firebase reference
ref.addValueEventListener(new ValueEventListener() {
// onDataChange will execute when the current value loaded and whenever it changes
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
// TODO: do whatever you need to do with the dataSnapshot
// tell the caller that we're done
semaphore.release();
}
@Override
public void onCancelled(FirebaseError firebaseError) {
}
});
// wait until the onDataChange callback has released the semaphore
semaphore.acquire();
// send our response message
ref.push().setValue("Oh really? Here is what I think of that");
Но это не будет работать на Android. И это хорошая вещь, потому что это плохая идея использовать этот тип блокирующего подхода во всем, что влияет на пользовательский интерфейс. Единственная причина, по которой я лежала в этом коде, - это то, что мне нужно было провести единичный тест.
В реальном коде, обращенном к пользователю, вы должны пойти для подхода, управляемого событиями. Поэтому вместо того, чтобы «ждать данных, чтобы прийти и затем отправить свое сообщение», я «когда данные приходит, отправить мое сообщение»:
// attach a value listener to a Firebase reference
ref.addValueEventListener(new ValueEventListener() {
// onDataChange will execute when the current value loaded and whenever it changes
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
// TODO: do whatever you need to do with the dataSnapshot
// send our response message
ref.push().setValue("Oh really? Here is what I think of that!");
}
@Override
public void onCancelled(FirebaseError firebaseError) {
}
});
Конечным результатом является точно такой же, но этот код не требует синхронизации и не блокирует Android.
package com.google.android.gms.tasks;
Tasks.await (taskFromFirebase);
На самом деле это должен быть принятый ответ. –
Действительно спасибо, я тоже искал это; но как это решить «выполнить операции блокировки, которые будут * возвращать необходимые данные»? Слушатели событий не являются задачами, и как вы это делаете? –
http://stackoverflow.com/questions/37215071/firebase-android-how-to-read-from-different-references-sequently –
Я придумал другой способ получения данных синхронно. Пререквизитом должно быть не на тему пользовательского интерфейса.
final TaskCompletionSource<List<Objects>> tcs = new TaskCompletionSource<>();
firebaseDatabase.getReference().child("objects").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Mapper<DataSnapshot, List<Object>> mapper = new SnapshotToObjects();
tcs.setResult(mapper.map(dataSnapshot));
}
@Override
public void onCancelled(DatabaseError databaseError) {
tcs.setException(databaseError.toException());
}
});
Task<List<Object>> t = tcs.getTask();
try {
Tasks.await(t);
} catch (ExecutionException | InterruptedException e) {
t = Tasks.forException(e);
}
if(t.isSuccessful()) {
List<Object> result = t.getResult();
}
Я протестировал свое решение, и оно отлично работает, но, пожалуйста, докажите, что я ошибаюсь!
, что этот новый SnapshotToObjects(); это любой встроенный класс, или вы создали свой собственный класс. если это ваш собственный класс, вы можете любезно рассказать об этом и его параметр –
Он реализован мной и является всего лишь картографом для DataSnapshot -> List
можете ли вы любезно показать, что метод –
- 1. Как загружать данные синхронно в приложении AngularJS
- 2. Возможно ли загружать данные из DynamoDB непосредственно из свиньи EMR?
- 3. Как получить данные синхронно с Firebase?
- 4. Есть ли способ синхронно получать данные от Firebase (Swift)?
- 5. Firebase Хранение загрузки синхронно
- 6. Использование Firebase observSingleEventOfType синхронно
- 7. Возможно ли, чтобы ngResource вызывался синхронно?
- 8. Возможно ли использовать синхронно обновляемую дооснащение?
- 9. Прием данных синхронно в Firebase
- 10. Извлечь данные из Firebase
- 11. Могу ли я загружать изображения синхронно с Glide?
- 12. синхронно загружать содержимое html в UIWebView
- 13. Защищает ли Firebase данные?
- 14. Как загружать данные базы данных Firebase в синхронном режиме?
- 15. Данные из Firebase несортированы
- 16. Возможно ли предотвратить запуск onDataChange() Firebase изначально?
- 17. Возможно ли загружать только часть двоичного файла
- 18. Выберите данные из firebase
- 19. Заставить асинхронный запрос Firebase выполнить синхронно?
- 20. Синхронизировать данные синхронно с JavaScript
- 21. Возможно ли загружать ассоциации с помощью nested_attributes?
- 22. Возможно ли получить данные из коллекцииViewCell?
- 23. Возможно ли регистрировать данные из игрового чата?
- 24. Возможно ли получить данные из объекта Flash?
- 25. Geospark: возможно ли вводить данные из HDFS
- 26. Возможно ли получить данные из шейдеров
- 27. Возможно ли получить данные из Google Spreadsheet?
- 28. Возможно ли захватить данные из предложения WHERE?
- 29. Возможно ли получить данные из утечки памяти?
- 30. Возможно ли получить данные из html-формы?
Thanks Frank! Я согласен с подходом, основанным на блокировании и событиях. Тем не менее, я должен выполнить несколько обновлений для WebView, так же, как это делает WebView.loadDataWithBaseURL() и HTTP-запросы (которые WebView выполняет) также блокируют. Причина, по которой я должен сделать это, а не сам WebView, заключается в том, что сервер недоступен для приложения, и я использую Firebase как «туннель». Любое лучшее решение будет высоко оценено. Кроме того, не разрешается ли решение семафора, если секция блокировки находится внутри события, которое может запускаться каждый раз, когда WebView запрашивает обновление? – Dani
Я почти уверен, что вышеприведенный фрагмент адреса показывает пример чата, который вы дали. Если вы используете-кейс на самом деле разные, предоставьте http://stackoverflow.com/help/mcve, пожалуйста. Код использует описание этого кода каждый день недели. –
Да, действительно! Спасибо @Frank! – Dani