Как вернуть DocumentSnapShot в результате применения метода?
Пользовательский объект, который принимает параметр (DocumentSnapShot documentsnapShot). также внутренний объект из Firebase, который извлекает снимок и устанавливает значения для моей пользовательской модели, также имеет свой аргумент (DocumentSnapShot documentsnapShot). Однако я хочу получить данные из Firebase и передать их в свой пользовательский аргумент, потому что мой принимает несколько данных, а не только Firebase. И невозможно выполнить итерацию Firestore без переопределения.
Вот код:
public UserSettings getUserSettings(DocumentSnapshot documentSnapshot){
Log.d(TAG, "getUserSettings: retrieving user account settings from firestore");
DocumentReference mSettings = mFirebaseFirestore.collection("user_account_settings").document(userID);
mSettings.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
@Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
UserAccountSettings settings = documentSnapshot.toObject(UserAccountSettings.class);
settings.setDisplay_name(documentSnapshot.getString("display_name"));
settings.setUsername(documentSnapshot.getString("username"));
settings.setWebsite(documentSnapshot.getString("website"));
settings.setProfile_photo(documentSnapshot.getString("profile_photo"));
settings.setPosts(documentSnapshot.getLong("posts"));
settings.setFollowers(documentSnapshot.getLong("followers"));
settings.setFollowing(documentSnapshot.getLong("following"));
}
});
}
Переведено автоматически
Ответ 1
Теперь вы не можете вернуть что-то, что еще не было загружено. Firestore загружает данные asynchronously
, поскольку для этого может потребоваться некоторое время. В зависимости от скорости вашего соединения и состояния, может потребоваться от нескольких сотен миллисекунд до нескольких секунд, прежде чем эти данные станут доступны. Если вы хотите передать settings
объект другому методу, просто вызовите этот метод внутри onSuccess()
метода и передайте этот объект в качестве аргумента. Итак, быстрое решение было бы следующим:
@Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
UserAccountSettings settings = documentSnapshot.toObject(UserAccountSettings.class);
yourMethod(settings);
}
Еще одна вещь, которую следует упомянуть, это то, что вам не нужно устанавливать те значения для объектов, у которых они уже есть. Вы уже получаете данные из базы данных в виде объекта.
Итак, помните, 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<DocumentSnapshot>() {
@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()
метода. Для получения дополнительной информации вы также можете взглянуть на это видео.
Ответ 2
Используйте LiveData
в качестве возвращаемого типа и наблюдайте за изменениями его значения для выполнения желаемой операции.
private MutableLiveData<UserAccountSettings> userSettingsMutableLiveData = new MutableLiveData<>();
public MutableLiveData<UserAccountSettings> getUserSettings(DocumentSnapshot documentSnapshot){
DocumentReference mSettings = mFirebaseFirestore.collection("user_account_settings").document(userID);
mSettings.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
@Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
UserAccountSettings settings = documentSnapshot.toObject(UserAccountSettings.class);
settings.setDisplay_name(documentSnapshot.getString("display_name"));
settings.setUsername(documentSnapshot.getString("username"));
settings.setWebsite(documentSnapshot.getString("website"));
settings.setProfile_photo(documentSnapshot.getString("profile_photo"));
settings.setPosts(documentSnapshot.getLong("posts"));
settings.setFollowers(documentSnapshot.getLong("followers"));
settings.setFollowing(documentSnapshot.getLong("following"));
userSettingsMutableLiveData.setValue(settings);
}
});
return userSettingsMutableLiveData;
}
Затем из вашего Activity/Fragment
наблюдения LiveData
и внутри onChanged
выполните желаемую операцию.
getUserSettings().observe(this, new Observer<UserAccountSettings>() {
@Override
public void onChanged(UserAccountSettings userAccountSettings) {
//here, do whatever you want on `userAccountSettings`
}
});