简体   繁体   English

如何作为方法的结果返回 DocumentSnapShot?

[英]How to return a DocumentSnapShot as a result of a method?

A custom object that takes a parameter of (DocumentSnapShot documentsnapShot).一个自定义的 object 参数为 (DocumentSnapShot documentsnapShot)。 also is an inner object from Firebase that retrieves a snapshot and set the values to my custom model also have its argument (DocumentSnapShot documentsnapShot).也是来自 Firebase 的内部 object 检索快照并将值设置为我的自定义 model 也有它的参数(DocumentSnapShot 文档napShot)。 However, I wish to get the data from Firebase and pass it to my custom argument because mine takes multiple data not only Firebase.但是,我希望从 Firebase 获取数据并将其传递给我的自定义参数,因为我不仅需要 Firebase 还需要多个数据。 And it's not possible to iterate Firestore without an override.如果没有覆盖,就不可能迭代 Firestore。

Here's the code:这是代码:

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"));
        }
    });
}

You cannot return something now that hasn't been loaded yet.您现在无法退回尚未加载的内容。 Firestore loads data asynchronously , since it may take some time for this. Firestore asynchronously加载数据,因为这可能需要一些时间。 Depending on your connection speed and the state, it may take from a few hundred milliseconds to a few seconds before that data is available.根据您的连接速度和状态,可能需要几百毫秒到几秒钟才能获得该数据。 If you want to pass settings object to another method, just call that method inside onSuccess() method and pass that object as an argument.如果要将settings对象传递给另一个方法,只需在onSuccess()方法中调用该方法并将该对象作为参数传递。 So a quick fix would be this:所以一个快速的解决方法是这样的:

@Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
    UserAccountSettings settings = documentSnapshot.toObject(UserAccountSettings.class);
    yourMethod(settings);
}

One more thing to mention is that you don't need to set the those values to object that already have them.还要提到的一件事是,您不需要将这些值设置为已经拥有它们的对象。 You are already getting the data from the database as an object.您已经从数据库中获取数据作为对象。

So remember, onSuccess() method has an asynchronous behaviour, which means that is called even before you are getting the data from your database.所以请记住, onSuccess()方法具有异步行为,这意味着它甚至在您从数据库中获取数据之前就被调用。 If you want to use the settings object outside that method, you need to create your own callback .如果要在该方法之外使用settings对象,则需要创建自己的callback To achieve this, first you need to create an interface like this:为了实现这一点,首先你需要创建一个这样的接口:

public interface MyCallback {
    void onCallback(UserAccountSettings settings);
}

Then you need to create a method that is actually getting the data from the database.然后,您需要创建一个实际从数据库中获取数据的方法。 This method should look like this:此方法应如下所示:

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);

        }
    });
}

In the end just simply call readData() method and pass an instance of the MyCallback interface as an argument wherever you need it like this:最后,只需简单地调用readData()方法并将MyCallback接口的实例作为参数传递到您需要的任何地方,如下所示:

readData(new MyCallback() {
    @Override
    public void onCallback(UserAccountSettings settings) {
        Log.d("TAG", settings.getDisplay_name());
    }
});

This is the only way in which you can use that object of UserAccountSettings class outside onSuccess() method.这是您可以在onSuccess()方法之外使用UserAccountSettings类的该对象的唯一方法。 For more informations, you can take also a look at this video .有关更多信息,您还可以观看此视频

Use LiveData as return type and observe the changes of it's value to execute desired operation.使用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;
}

Then from your Activity/Fragment observe the LiveData and inside onChanged do your desired operation.然后从您的Activity/Fragment观察LiveData并在onChanged内部执行您想要的操作。

getUserSettings().observe(this, new Observer<UserAccountSettings>() {
    @Override
    public void onChanged(UserAccountSettings userAccountSettings) {
        //here, do whatever you want on `userAccountSettings`
    }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Flutter Firebase 在同一小部件中返回 Querysnapshot 和 DocumentSnapshot - Flutter Firebase return a Querysnapshot and DocumentSnapshot in the same widget 任务<documentsnapshot> .Result.Exists 总是返回 False</documentsnapshot> - Task<DocumentSnapshot>.Result.Exists Always Returns False Class '列表<documentsnapshot> ' 在 Flutter 中没有实例方法 'call'</documentsnapshot> - Class 'List<DocumentSnapshot>' has no instance method 'call' in Flutter 如何在 Flutter 中使用 Firestore 中的 DocumentSnapshot 填充 Map? - How to fill Map from DocumentSnapshot in Using Firestore in Flutter? Firebase DocumentSnapshot 字段 - Firebase DocumentSnapshot fields 您如何通过 flutter 中的云功能从 firestore 获取 documentSnapshot? - How do you get a documentSnapshot from firestore over a cloud function in flutter? 如何根据具体结果在flutter中返回不同的页面? - How to return a different pages in flutter accordingly to specific result? Firestore iOS DocumentSnapshot `createTime` - Firestore iOS DocumentSnapshot `createTime` firebase笔交易的get操作如何即时返回结果 - How do get operations on firebase transactions instantly return the result 如何使用 on() firebase 数据库方法返回值给调用 function? - how to use on() firebase database method to return value to the calling function?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM