デシリアライズしながら、リストをアンドロイド-期待が、クラスのjava.util.HashMapを得ました

はいタヴァン:

私はアンドロイドでFirebaseからレストランのすべてのリストを取得したいです。 私のデータベース

ここに私のコードは次のとおりです。

boolean delivery;
String openTime, closeTime, restaurantName;
long likes;
List<String> utilities;

List<RestaurantModel> listRes;

DatabaseReference dataResReference;

public RestaurantModel(){
    dataResReference = FirebaseDatabase.getInstance().getReference().child("restaurants");
}

public List<RestaurantModel> getallRestaurant(){

    listRes = new ArrayList<>();
    ValueEventListener valueEventListener = new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                for (DataSnapshot dataValues : dataSnapshot.getChildren()){
                    RestaurantModel restaurantModel = dataValues.getValue(RestaurantModel.class);
                    listRes.add(restaurantModel);
                }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    };
    dataResReference.addListenerForSingleValueEvent(valueEventListener);
    return  listRes;
}

しかし、私は例外を取得します

Expected a List while deserializing, but got a class java.util.HashMap

でRestaurantModel restaurantModel = dataValues.getValue(RestaurantModel.class)。

アップデート:ベースはアレックスマモのanswserに、私は私のコードを変更します:

public void getAllRestaurant(final WhereInterface whereInterface){
    ValueEventListener valueEventListener = new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            //go to node restaurant because datasnapshot is parent node
            DataSnapshot dataSnapshotRes = dataSnapshot.child("restaurants");
            //

            for (DataSnapshot valueRes : dataSnapshotRes.getChildren()){
                RestaurantModel restaurantModel = valueRes.getValue(RestaurantModel.class);
                whereInterface.getAllRestaurantModel(restaurantModel);

            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    };
    databaseReferenceRoot.addListenerForSingleValueEvent(valueEventListener);
}

しかし、私はまだ(この例外が発生しました:。

誰もがなぜ知っていることができますか?

そして、そこに解決策はありますか?

どうもありがとうございます!

アレックス・マモ:

あなたのコード内の2つの問題があります。最初のものは、このエラーになります:

デシリアライズしながら、リストの予想が、クラスのjava.util.HashMapを得ました

次のコード行を使用して解決することができ:

ValueEventListener valueEventListener = new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        List<RestaurantModel> listRes = new ArrayList<>();

        for (DataSnapshot dataValues : dataSnapshot.getChildren()){
            RestaurantModel restaurantModel = dataValues.getValue(RestaurantModel.class);
            listRes.add(restaurantModel);
        }

        //Do what you need to do with listRes
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        throw databaseError.toException(); //Don't ignore errors
    }
};
dataResReference.addListenerForSingleValueEvent(valueEventListener);

そして、第二の問題は、あなたがまだロードされていない今、何かを返すことができないということです。Firebase APIがあるasynchronousことを意味し、onDataChange()それが呼び出さだ直後メソッドの戻りをし、それを返すタスクからのコールバックはいつか後に呼び出されます。それはかかる時間についての保証はありません。それは数秒に数百ミリ秒からかかる場合がありますので、そのデータが利用可能になる前に。そのメソッドが返すはすぐに、あなたのでlistResリストには、復帰しようとしている、このメソッドの非同期動作のために空になります。

基本的には、非同期のAPIから同期した値を返すようにしようとしています。それはいい考えではありません。意図したとおりにあなたは非同期APIを処理する必要があります。

この問題への迅速な解決策を使用することですlistRes唯一の内側にリストがonDataChange()そうでない場合、私はあなたがこのことから私の答えの最後の部分を参照してくださいお勧めします、(上記のコード行のように)メソッドのポスト私はそれを行うことができる方法を説明している中でカスタムコールバックを使用しました。また、これを見てとることができ、映像をよりよく理解するために。

編集:

public void getAllRestaurant(){
    ValueEventListener valueEventListener = new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            List<RestaurantModel> listRestaurant = new ArrayList<>();

            for (DataSnapshot valueRes : dataSnapshot.getChildren()){
                RestaurantModel restaurantModel = valueRes.getValue(RestaurantModel.class);
                Log.d("Test", restaurantModel.getRestaurantName());
                listRestaurant.add(restaurantModel);
            }

            //Do what you need to do with listRes
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
            throw databaseError.toException();
        }
    };
    DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();        
    rootRef.child("restaurants").addListenerForSingleValueEvent(valueEventListener);
}

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=189973&siteId=1