Вы не можете вернуть то, что еще не загружено. Firestore загружает данные asynchronously
, так как для этого может потребоваться некоторое время. В зависимости от скорости соединения и состояния, может потребоваться от нескольких сотен миллисекунд до нескольких секунд, прежде чем эти данные будут доступны. Если вы хотите передать объект settings
другому методу, просто вызовите этот метод внутри метода onSuccess()
и передайте этот объект в качестве аргумента. Таким образом, быстрое исправление будет следующим:
@Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
UserAccountSettings settings = documentSnapshot.toObject(UserAccountSettings.class);
yourMethod(settings);
}
Еще одно замечание: вам не нужно устанавливать эти значения для объекта, который уже имеет их. Вы уже получаете данные из базы данных в качестве объекта.
blockquote>Так что помните, что метод
onSuccess()
имеет асинхронное поведение, а это означает, что вызывается еще до того, как вы получите данные из своего база данных. Если вы хотите использовать объектsettings
вне этого метода, вам нужно создать свой собственныйcallback
. Для этого сначала нужно создать такой интерфейс:public interface MyCallback { void onCallback(UserAccountSettings settings); }
Затем вам нужно создать метод, который фактически получает данные из базы данных. Этот метод должен выглядеть так:
public void readData(MyCallback myCallback) { DocumentReference mSettings = mFirebaseFirestore.collection("user_account_settings").document(userID); mSettings.get().addOnSuccessListener(new OnSuccessListener
() { @Override public void onSuccess(DocumentSnapshot documentSnapshot) { UserAccountSettings settings = documentSnapshot.toObject(UserAccountSettings.class); myCallback.onCallback(settings); } }); } . В конце просто просто вызовите метод
readData()
и передайте экземпляр интерфейсаMyCallback
в качестве аргумента везде, где вам это нужно:readData(new MyCallback() { @Override public void onCallback(UserAccountSettings settings) { Log.d("TAG", settings.getDisplay_name()); } });
Это единственный способ, которым вы можете использовать этот объект класса
UserAccountSettings
вне методаonSuccess()
. Для получения дополнительной информации вы также можете посмотреть видео .
В спецификации HTML 5 указано, что alert()
, prompt()
и т. д. не будут доступны во время события window.unload()
. Подробнее см. В window.unload () . Вы можете проверить результат, используя console.log('success');
вместо alert()
.
Ваша функция и вызов Ajax выглядят прекрасно, поэтому я предполагаю, что окно вашего браузера закрыто до того, как вызов ajax успеет перейти на сервер и обратно. Вызов ajax может вернуть что-то, когда окно закрывается, попробуйте добавить функцию ошибки к вашему вызову ajax, чтобы убедиться, что это так:
error: function (xhr, textStatus) {
alert('Server error: '+ textStatus);
}
Я считаю, что вам нужно сделать синхронный запрос (по умолчанию он асинхронный), используя параметр async : false
.
Возможно, у вас будет больше успеха с использованием события onbeforeunload
?
$(window).bind('beforeunload', ...
Попробуйте вызвать его с помощью async = false;
jQuery.ajax({url:"http://localhost:8888/test.php?", async:false})
Я просто попробовал.
Лучшее решение - использовать navigator.sendBeacon . Это совершенно новая функциональность, которая начинает внедряться в новые версии браузеров. Функция доступна в браузерах, новее, чем Chrome 39 и Firefox 31. Она не поддерживается Internet Explorer и Safari на момент написания. Чтобы убедиться, что ваш запрос отправлен в браузерах, которые еще не поддерживают новую функциональность, вы можете использовать это решение:
var navigator.sendBeacon = navigator.sendBeacon || function (url, data) {
var client = new XMLHttpRequest();
client.open("POST", url, false); // third parameter indicates sync xhr
client.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
client.send(data);
};
Эта функция не позволяет вам регистрировать обратный вызов onsuccess.