私はアンドロイドで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);
}