programing

Android에서 Firebase 데이터 스냅샷에서 개체 목록을 추출하는 방법

kingscode 2023. 6. 10. 15:39
반응형

Android에서 Firebase 데이터 스냅샷에서 개체 목록을 추출하는 방법

모든 Firebase를 변환합니다.DataSnapshot안드로이드 목록에 있는 아이들.

이와 같은 것:

mFirebaseRef = new Firebase(FIREBASE_URL);

mFirebaseRef.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        List<String> td = (ArrayList<String>) dataSnapshot.getValue();
        //notifyDataSetChanged();
    }

    @Override
    public void onCancelled(FirebaseError firebaseError) {

    }
});

아래 코드가 작동하기를 바랍니다.

Firebase ref = new Firebase(FIREBASE_URL);

  ref.addValueEventListener(new ValueEventListener() {
      @Override
      public void onDataChange(DataSnapshot snapshot) {
          Log.e("Count " ,""+snapshot.getChildrenCount());
          for (DataSnapshot postSnapshot: snapshot.getChildren()) {
            <YourClass> post = postSnapshot.getValue(<YourClass>.class);
            Log.e("Get Data", post.<YourMethod>());
          }
      }
      @Override
      public void onCancelled(FirebaseError firebaseError) {
          Log.e("The read failed: " ,firebaseError.getMessage());
      }
  });

Firebase는 다음 형식으로 일련의 값을 저장합니다.

"-K-Y_Rhyxy9kfzIWw7Jq": "Value 1"
"-K-Y_RqDV_zbNLPJYnOA": "Value 2"
"-K-Y_SBoKvx6gAabUPDK": "Value 3"

만약 당신이 그것들을 그렇게 가지고 있다면, 당신은 잘못된 유형을 가지고 있는 것입니다.위의 구조는 다음과 같이 표현됩니다.Map전혀 아닌List:

mFirebaseRef = new Firebase(FIREBASE_URL);

mFirebaseRef.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        Map<String, Object> td = (HashMap<String,Object>) dataSnapshot.getValue();

        List<Object> values = td.values();

        //notifyDataSetChanged();
    }

    @Override
    public void onCancelled(FirebaseError firebaseError) {

    }
});
FirebaseDatabase mFirebaseDatabase = FirebaseDatabase.getInstance();
 DatabaseReference databaseReference =    mFirebaseDatabase.getReference(FIREBASE_URL);
        databaseReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                for (DataSnapshot childDataSnapshot : dataSnapshot.getChildren()) {
                    Log.v(TAG,""+ childDataSnapshot.getKey()); //displays the key for the node
                    Log.v(TAG,""+ childDataSnapshot.child(--ENTER THE KEY NAME eg. firstname or email etc.--).getValue());   //gives the value for given keyname
                }
            }
        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

도움이 되길 바랍니다!

프랭크가 말했듯이 파이어베이스는 일련의 값을 다음의 형식으로 저장합니다."key": "Value"그것은 지도 구조입니다.

이 시퀀스에서 목록을 가져오려면 다음 작업을 수행해야 합니다.

  1. GenericType 초기화문자열과 개체의 해시맵이 있는 표시기입니다.
  2. GenericType으로 DataSnapShot 값 가져오기지도로 표시합니다.
  3. HashMap 값을 사용하여 ArrayList를 초기화합니다.

GenericTypeIndicator<HashMap<String, Object>> objectsGTypeInd = new GenericTypeIndicator<HashMap<String, Object>>() {};
Map<String, Object> objectHashMap = dataSnapShot.getValue(objectsGTypeInd);
ArrayList<Object> objectArrayList = new ArrayList<Object>(objectHashMap.values());

잘 작동합니다. 도움이 되길 바랍니다.

저는 다음과 같은 일을 했습니다.

Firebase ref = new Firebase(FIREBASE_URL);
ref.addValueEventListener(new ValueEventListener() {

@Override
public void onDataChange(DataSnapshot snapshot) {
    Map<String, Object> objectMap = (HashMap<String, Object>)    
             dataSnapshot.getValue();
    List<Match> = new ArrayList<Match>();
    for (Object obj : objectMap.values()) {
        if (obj instanceof Map) {
            Map<String, Object> mapObj = (Map<String, Object>) obj;
            Match match = new Match();
            match.setSport((String) mapObj.get(Constants.SPORT));
            match.setPlayingWith((String) mapObj.get(Constants.PLAYER));
            list.add(match);
        }
    }
  }
  @Override
  public void onCancelled(FirebaseError firebaseError) {

  }
});

제 경우에는 주어진 해결책만 잘 작동했습니다.

Firebase Array List 구조의 스크린샷:

여기에 이미지 설명 입력

데이터 스냅샷에서 Firebase에서 전체 목록을 가져오는 방법.

GenericTypeIndicator<Map<String, List<Education>>> genericTypeIndicator = new GenericTypeIndicator<Map<String, List<Education>>>() {};
Map<String, List<Education>> hashMap = dataSnapshot.getValue(genericTypeIndicator);

for (Map.Entry<String,List<Education>> entry : hashMap.entrySet()) {
      List<Education> educations = entry.getValue();
        for (Education education: educations){
             Log.i(TAG, education.Degree);
         }
}

교육.java: (모델 클래스).

public class Education implements Serializable{

    public String Degree;
    public String Result;
}

이것이 잘 작동하기를 바랍니다.

    @Override
       public void onDataChange(DataSnapshot dataSnapshot) {
           for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
               User user = postSnapshot.getValue(User.class);
               list.add(user);
           }
           for (int i=0;i<list.size();i++)
           {
               Log.e("Name",list.get(i).getname());
               Log.e("Phone",list.get(i).getphone());

           }
       }
       @Override
       public void onCancelled(FirebaseError firebaseError) {
       Log.e("error",firebaseError.getMessage());
       }
   });

클래스 모델

class User{

String name;

String phone;

public String getname() {
    return name;
}

public void setname(String name) {
    this.name = name;
}


public String getphone() {
    return phone;
}

public void setphone(String phone) {
    this.phone = phone;
}
}

목록 바인딩

List<User> list= new ArrayList <>();

당신을 위한 이 일

만약 당신이 Kotlin을 사용한다면, 다음은 좋은 해결책입니다.

myRef.addListenerForSingleValueEvent(object : ValueEventListener {
  override fun onDataChange(dataSnapshot: DataSnapshot) {
      val list = dataSnapshot.children.map { it.getValue(YourClass::class.java)!! }
      Log.d("TAG", "Value is: $list")
}

Firebase에서 데이터 저장 및 검색(사용되지 않는 버전 2.4.2)

Firebase fb_parent = new Firebase("YOUR-FIREBASE-URL/");
Firebase fb_to_read = fb_parent.child("students/names");
Firebase fb_put_child = fb_to_read.push(); // REMEMBER THIS FOR PUSH METHOD

//INSERT DATA TO STUDENT - NAMES  I Use Push Method
fb_put_child.setValue("Zacharia"); //OR fb_put_child.setValue(YOUR MODEL) 
fb_put_child.setValue("Joseph"); //OR fb_put_child.setValue(YOUR MODEL) 
fb_put_child.setValue("bla blaaa"); //OR fb_put_child.setValue(YOUR MODEL) 

//GET DATA FROM FIREBASE INTO ARRAYLIST
fb_to_read.addValuesEventListener....{
    public void onDataChange(DataSnapshot result){
        List<String> lst = new ArrayList<String>(); // Result will be holded Here
        for(DataSnapshot dsp : result.getChildren()){
            lst.add(String.valueOf(dsp.getKey())); //add result into array list
        }
        //NOW YOU HAVE ARRAYLIST WHICH HOLD RESULTS




for(String data:lst){ 
         Toast.make(context,data,Toast.LONG_LENGTH).show; 
       }
    }
}
mDatabase.child("token").addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
              for (DataSnapshot snapshot:dataSnapshot.getChildren())
              {
                 String key= snapshot.getKey();
                 String value=snapshot.getValue().toString();
              }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                Toast.makeText(ListUser.this,databaseError.toString(),Toast.LENGTH_SHORT).show();
            }
        });

자녀가 없는 경우에만 작업SubChild

여기에 이미지 설명 입력

매력적인 작품

final DatabaseReference senderDb = FirebaseDatabase.getInstance().getReference(Constant.NODE_MESSAGE).child(myId + "_" + otherId);

    senderDb.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Map<String, Object> td = (HashMap<String,Object>) dataSnapshot.getValue();

            for (DataSnapshot childDataSnapshot : dataSnapshot.getChildren()) {
                DatabaseReference objRef = senderDb.child( childDataSnapshot.getKey());
                Map<String,Object> taskMap = new HashMap<String,Object>();
                taskMap.put("is_read", "1");
                objRef.updateChildren(taskMap); //should I use setValue()...?
                Log.v("Testing",""+ childDataSnapshot.getKey()); //displays the key for the node
            }

            //notifyDataSetChanged();
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }

    });

사용자 정의 Deserializer를 작성한 다음 루프하여 hasmap 값을 가져와야 합니다.

사용자 지정 역직렬화기:-

public class UserDetailsDeserializer implements JsonDeserializer<AllUserDetailsKeyModel> {
  /*
    bebebejunskjd:{
      "email": "akhilbv1@gmail.com",
          "mobileNum": "12345678",
          "password": "1234567",
          "username": "akhil"}*/
  @Override public AllUserDetailsKeyModel deserialize(JsonElement json, Type typeOfT,
      JsonDeserializationContext context) throws JsonParseException {

    final JsonObject jsonObject = json.getAsJsonObject();

    Gson gson = new Gson();

    Type AllUserDetailsResponseModel =
        new TypeToken<HashMap<String, AllUserDetailsResponseModel>>(){}.getType();

    HashMap<String, AllUserDetailsResponseModel> user =
        gson.fromJson(jsonObject, AllUserDetailsResponseModel);
    AllUserDetailsKeyModel result = new AllUserDetailsKeyModel();
    result.setResult(user);
    return result;
  }


}

코멘트에 있는 코드는 나의 객체 모델이며 당신은 아래와 같이 AllUserDetailsKeyModel을 당신의 모델 클래스로 바꾸고 이것을 나머지 클라이언트에 추가해야 합니다:-

private Converter.Factory createGsonConverter() {
    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(AllUserDetailsKeyModel.class, new UserDetailsDeserializer());
    Gson gson = gsonBuilder.create();
    return GsonConverterFactory.create(gson);
  }

이것은 개조를 위한 사용자 정의 컨버터입니다.

onResponse에서 hasmap으로 루프하고 키별로 값을 가져오면 내 모델 클래스는 다음과 같습니다.

public class AllUserDetailsKeyModel {

  private Map<String, AllUserDetailsResponseModel> result;

  public Map<String, AllUserDetailsResponseModel> getResult() {
    return result;
  }

  public void setResult(Map<String, AllUserDetailsResponseModel> result) {
    this.result = result;
  }

}

아마도 당신은 Type을 제공해야 할 것입니다. 여기서 T는 당신의 데이터 Type이고 내 모델은 오직 해시맵과 그것을 위한 게터와 세터로만 구성됩니다.

그리고 마지막으로 아래와 같이 사용자 정의 컨버터를 개조하도록 설정합니다..addConverterFactory(createGsonConverter())

더 명확한 설명이 필요하시면 말씀해주세요.

일반 유형 사용FireBase ArrayList 구조화된 데이터베이스에서 하위 노드 목록을 가져오는 표시기

   //Start of Code
   Firebase ref = new Firebase(FIREBASE_URL);
   ref.addValueEventListener(new ValueEventListener(){
      @Override
      public void onDataChange(DataSnapshot snapshot){
         GenericTypeIndicator<List<YourClassName>> t = new GenericTypeIndicator<List<YourClassName>>{};
         List<YourClassName> messages = snapshot.getValue(t);
         Log.d("Get Data Size", messages.size());
          }
      }
      @Override
      public void onCancelled(FirebaseError firebaseError){
          Log.e("The read failed: ",firebaseError.getMessage());
      }
   });

당신의 문제는 당신의 코드가 작동하지 않는 이유입니다.

이것은 당신의 코드입니다:

Firebase ref = new Firebase(FIREBASE_URL);

  ref.addValueEventListener(new ValueEventListener() {
      @Override
      public void onDataChange(DataSnapshot snapshot) {
          Log.e("Count " ,""+snapshot.getChildrenCount());
          for (DataSnapshot postSnapshot: snapshot.getChildren()) {
            <YourClass> post = postSnapshot.getValue(<YourClass>.class);
            Log.e("Get Data", post.<YourMethod>());
          }
      }
      @Override
      public void onCancelled(FirebaseError firebaseError) {
          Log.e("The read failed: " ,firebaseError.getMessage());
      }
  })

가장 간단한 것을 놓치게 됩니다.getChildren()

FirebaseDatabase db = FirebaseDatabase.getInstance();
DatabaseReference reference = FirebaseAuth.getInstance().getReference("Donald Trump");

reference.addValueEventListener(new ValueEventListener() {
   @Override
   public void onDataChange(DataSnapshot dataSnapshot) {

            int count = (int) dataSnapshot.getChildrenCount(); // retrieve number of childrens under Donald Trump

            String[] hairColors = new String[count];

            index = 0;
            for (DataSnapshot datas : dataSnapshot.getChildren()){

                hairColors[index] = datas.getValue(String.class);

            }
            index ++

            for (int i = 0; i < count; i++)
            Toast(MainActivity.this, "hairColors : " + hairColors[i], toast.LENGTH_SHORT).show();

            }

    }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }

    });
ArrayList<String> keyList = new ArrayList<String>();
mKeyRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot childDataSnapshot : dataSnapshot.getChildren()) {
                String temp = childDataSnapshot.getKey();
                keyList.add(temp);
                i = keyList.size();

            }
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {
            throw databaseError.toException();
        }
    });

이 코드는 모든 Firebase 키를 배열 목록에 추가하는 데 잘 작동하며, 다른 정적 값의 Firebase 값으로 할 수 있습니다.

DatabaseReference mRootRef = FirebaseDatabase.getInstance().getReference();
        DatabaseReference mMainMenuRef = mRootRef.child("tut_master");//main
        DatabaseReference mSubMenuRef = mMainMenuRef.child("english");//sub
        List<Tutorial>   tutorialNames=new ArrayList<>();
        mSubMenuRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                for(DataSnapshot ds : dataSnapshot.getChildren()) {
                    long id = ds.child("id").getValue(Long.class);
                    String name = ds.child("name").getValue(String.class);

                    Tutorial tut = new Tutorial();
                    tut.setTutId(id+"");
                    tut.setTutName(name);
                    tutList.add(tut);

                }

            }

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

            }


        });
 private FirebaseDatabase firebaseDatabase=  FirebaseDatabase.getInstance();
    private DatabaseReference databaseReference=  firebaseDatabase.getReference();
    private DatabaseReference mChildReference= databaseReference.child("data");

  mChildReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                for(DataSnapshot ds : dataSnapshot.getChildren()) {
                    User commandObject = ds.getValue(User.class);
                    Log.d("TAG", commandObject.getMsg());
                }
                Toast.makeText(MainActivity.this,dataSnapshot.toString(),Toast.LENGTH_SHORT).show();
            }

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

            }
        });

이렇게 하면 도움이 됩니다. String msg를 포함하는 모델 클래스를 생성하면 됩니다.

Gson을 사용하는 것이 제가 가장 좋아하는 해결책입니다.

mFirebaseRef.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        Type StringListType = new TypeToken<List<String>>(){}.getType();
        List<String> td = new Gson().fromJson(dataSnapshot.getValue(), StringListType);
    }
});

TypeToken을 가져오는 코드가 직관적이지 않다고 생각하는 경우.필요한 모든 유형을 포함하는 클래스를 작성할 수 있습니다.그래서 다음 번에는 그런 유형들을 빨리 구할 수 있습니다.

class TypeTokens{
    static public final Type StringListType = new TypeToken<List<String>>(){}.getType();
    static public final Type StringMapType = new TypeToken<Map<String, String>>(){}.getType();
    static public final Type LongMapType = new TypeToken<Map<String, Long>>(){}.getType();
    static public final Type DateMapType = new TypeToken<Map<String, Date>>(){}.getType();
}

여기 제 2센트 기부금이 있습니다(코틀린에서).

    private fun getData(childUid:String) {
    
    refDB = firebaseDB.reference.child(MAIN_DATABASE_FOLDER).child(childUid)
    if(childEventDataListener == null) {
        childEventDataListener = object : ChildEventListener {
            override fun onChildAdded(snapshot: DataSnapshot, previousChildName: String?) {
                
                for(snap in snapshot.children) {
                    val newParcel = snapshot.getValue(YourClassConverter::class.java)!!
                }
            }
            
            override fun onChildChanged(snapshot: DataSnapshot, previousChildName: String?) { }
            override fun onChildRemoved(snapshot: DataSnapshot) { }
            override fun onChildMoved(snapshot: DataSnapshot, previousChildName: String?) {}
            override fun onCancelled(error: DatabaseError) {}
        }
        refDB.addChildEventListener(childEventDataListener!!)
    }
}

클래스 YourClassConverter는 아래에 표시된 getValue 헤더의 설명에 명시된 대로 이 규칙을 따라야 합니다.저는 일부가 파이어베이스에 정의되지 않은 경우 전달되는 기본값을 제어할 수 있기 때문에 이 컨버터를 사용하는 것을 선호합니다.

이 방법은 이 스냅샷에 포함된 데이터를 선택한 클래스로 마셜링하는 데 사용됩니다.클래스는 두 가지 단순 제약 조건을 충족해야 합니다.클래스에는 인수를 사용하지 않는 기본 생성자가 있어야 합니다. 클래스에는 할당할 속성에 대한 공용 게터를 정의해야 합니다.인스턴스가 역직렬화되면 공용 게터가 없는 속성이 기본값으로 설정됩니다. 예 클래스는 다음과 같습니다.

 class Message {
     private String author;
     private String text;

     private Message() {}

     public Message(String author, String text) {
         this.author = author;
         this.text = text;
     }

     public String getAuthor() {
         return author;
     }

     public String getText() {
         return text;
     }
 }


 // Later
 Message m = snapshot.getValue(Message.class);

언급URL : https://stackoverflow.com/questions/32886546/how-to-extract-a-list-of-objects-from-firebase-datasnapshot-on-android

반응형