retrieve the value of an ArrayList inside a repeating function - java

I'm trying to retrieve the array list generated in the function recuperarPessoasModelo(), but it only runs much later than I need so the value passed to revelaPessoas() is null, does anyone know any way I can run this function and just get the value after recuperarPessoasModelo() is executed? I can't put it inside because since it has a for loop it will run X times and generate a repeating list
The .Json in the DB looks like this:
Perfil{
PcCPoh01wscJj7jJBQQorme7Rqq1{
status:online
name: Carl Johnson
age: 21
sex: male}
t3IeEKy7XxdGeLYRxw2G1djNHdp2{
status:online
name: John Marston
age: 33
sex: male}
}
Requisicoes{
t3IeEKy7XxdGeLYRxw2G1djNHdp2{
Enviadas{
PcCPoh01wscJj7jJBQQorme7Rqq1{
idPessoa:PcCPoh01wscJj7jJBQQorme7Rqq1
status: Aguardando
}
}
}
}
the class in question:
public class Perfil_outter extends AppCompatActivity{
private List <RequisicoesCitty> requisicao = new ArrayList<>();
private List <ModeloPerfil> pessoaQuestao = new ArrayList<>();
private String idComp;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
carregarIds();
revelaPessoa()
}
public List<ModeloPerfil> getPessoaQuestao() {
return pessoaQuestao;
}
public void setPessoaQuestao(List<ModeloPerfil> pessoaQuestao) {
this.pessoaQuestao = pessoaQuestao;
}
public void carregarIds(){
Log.d("Part 1", "Working");
DatabaseReference firebaseRef = ConfiguracaoFirebase.getFirebaseDatabase();
DatabaseReference idsRef = firebaseRef.child("Requisicoes");
Query refId = idsRef.child(usuarioAtual.getId()).child("Enviadas").orderByChild("id");
refId.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for(DataSnapshot ds: snapshot.getChildren()) {
RequisicoesCitty reqSnapshots = ds.getValue(RequisicoesCitty.class);
Log.d("IdPessoas",reqSnapshots.getIdPessoa());
requisicao.add(reqSnapshots);
}
carregarRequisicoes();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
public void carregarRequisicoes(){
if(requisicao.isEmpty()){
Log.d("Não encontrado", "Nenhuma requisição Citty");
}
for(RequisicoesCitty requisicao: requisicao) {
Log.d("Part 2", "Working");
DatabaseReference firebaseRef = ConfiguracaoFirebase.getFirebaseDatabase();
Query requisicoesEnviadas = firebaseRef.child("Requisicoes").child(usuarioAtual.getId())
.child("Enviadas").child(requisicao.getIdPessoa());
requisicoesEnviadas.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
RequisicoesCitty reqSnap = snapshot.getValue(RequisicoesCitty.class);
idComp = reqSnap.getIdPessoa();
recuperarPessoasModelos();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
public void recuperarPessoasModelos(){
Log.d("Part 3", "Working");
DatabaseReference firebaseRef = ConfiguracaoFirebase.getFirebaseDatabase();
Query pessoas = firebaseRef.child("Perfil").child(idComp);
pessoas.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
ModeloPerfil pessoas = snapshot.getValue(ModeloPerfil.class);
pessoaQuestao.add(pessoas);
setPessoaQuestao(pessoaQuestao);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
public void revelaPessoas(){
for(ModeloPerfil modelo: getPessoaQuestao()){
Log.d("Funcionar", modelo.getNome());
}
}
}
did you understand my problem? my goal is to get the value modelo.getNome() inside of revelaPessoas back and display but it runs sooner than it should

You're calling recuperarPessoasModelos each time that carregarRequisicoes loops through one of its for(RequisicoesCitty requisicao: requisicao) {. This is totally fine, but I'm guessing that recuperarPessoasModelos is not handling these multiple calls correctly.
If you only want to call recuperarPessoasModelos once all requisicao are done, you can check a counter like this:
List snapshots = new List(); // 👈 a list to track the snapshots we have already loaded
for(RequisicoesCitty requisicao: requisicao) {
Log.d("Part 2", "Working");
DatabaseReference firebaseRef = ConfiguracaoFirebase.getFirebaseDatabase();
Query requisicoesEnviadas = firebaseRef.child("Requisicoes").child(usuarioAtual.getId())
.child("Enviadas").child(requisicao.getIdPessoa());
requisicoesEnviadas.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
snapshots.add(snapshot); // 👈 add snapshot to list
RequisicoesCitty reqSnap = snapshot.getValue(RequisicoesCitty.class);
idComp = reqSnap.getIdPessoa();
if (snapshots.size() == requisicao.size()) { // 👈 check if we got all of them
recuperarPessoasModelos();
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException(); // 👈 never ignore errors
}

Related

How can I change the value of child in Firebase database?

I want to change the value of child "toggleStatus" under Reference "BetSlip" as shown below. The already set value is "on" so I want such that when I click the button the value of "toggleStatus" is changed to "off"
BetSlipActivity.toggleCollapse.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String timeStamp = betSlip.get(position).getTimeStamp();
String toggleStatus = betSlip.get(position).getToggleStatus();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("BetSlip");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot ds: snapshot.getChildren()) {
String timestamp = ""+ ds.child("timeStamp").getValue();
String toggleStatus = ""+ ds.child("toggleStatus").getValue();
if (timeStamp.equals(timestamp) && toggleStatus.equals("on")) {
//set value to off
}
if (timeStamp.equals(timestamp) && toggleStatus.equals("off")) {
//set value to on
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
});
If you've got the DataSnapshot for a path in the database, it's easy to get the DatabaseReference that you need to update it:
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("BetSlip");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot ds: snapshot.getChildren()) {
String timestamp = ""+ ds.child("timeStamp").getValue();
String toggleStatus = ""+ ds.child("toggleStatus").getValue();
if (timeStamp.equals(timestamp) && toggleStatus.equals("on")) {
ds.child("toggleStatus").getRef().setValue("off");
}
if (timeStamp.equals(timestamp) && toggleStatus.equals("off")) {
ds.child("toggleStatus").getRef().setValue("on");
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException(); // never ignore errors
}
});
Since you're updating the node based on its existing value, strictly speaking you might need to use a transaction for it.

Get data from firebase from a specific position

Hy, I'm writing an application that has to get specific data from firebase using the position of the item in the listView. My problem is that I have no idea how to take it this item on firebase.
For all child of Torneo I have to control all the nameCreator.
I have tried this:
public Boolean RegisterUser(Data data, final int position, final Context c){
boolean registration;
final ArrayList<String> Creator = new ArrayList<>();
databaseReference.orderByChild("Tornei").equalTo(Integer.toString(position)).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot datas: dataSnapshot.getChildren()){
Creator.add(data.child("nameCreator").getValue().toString());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
if(Creator.equals(data.getNameCreator())){
registration = false;
}else{
registration = true;
}
return registration;
}
Data is a class with some getter and setter that I have created.
position is the position of the element on the list view.
Thanks for answers.
Change the following:
databaseReference.orderByChild("Tornei").equalTo(Integer.toString(position)).addListenerForSingleValueEvent(new ValueEventListener() {
into this:
databaseReference.child("Tornei").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot datas: dataSnapshot.getChildren()){
Creator.add(datas.child("nameCreator").getValue().toString());
if(Creator.equals(data.getNameCreator())){
registration = false;
}else{
registration = true;
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Then you will be able to loop and retrieve the value of nameCreator
It's easy.
【Step 1 | Get Snapshot Data and Save in Global Variable】
DatabaseReference rootReference = FirebaseDatabase.getInstance().getReference();
DatabaseReference fruitsReference = rootReference.child("fruits");
DataSnapshot fruitsData;
#Override
protected void onStart() {
super.onStart();
fruitsReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshots) {
fruitsData = dataSnapshots;
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
【Step 2 | Find Your Target Position through the Loop】
public void onClick(View view) {
int index = 0;
for (DataSnapshot childSnapshot : fruitsData.getChildren()) {
if (index == 1) { //your target position
DatabaseReference currentFruitReference = childSnapshot.getRef();
currentFruitReference.setValue("peach"); //do whatever you want
}
index++;
}
}

how to get specific nodes under unique keys in firebase realtime database android

I am trying to get data from nested nodes under unique keys. Each key is identical. It's difficult for me to deal with such problem help please.
I have tried ChildEventListener on database reference but not succeeded.
here is the code i am using to retreive data
InfoFragment.java
auth = FirebaseAuth.getInstance();
mFirebaseDatabase = FirebaseDatabase.getInstance().getReference("Seller").getRef().child("ImpInfo");
mFirebaseDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot postDataSnapshot : dataSnapshot.getChildren()) {
ShopSellerInfo shopSellerInfo = postDataSnapshot.getValue(ShopSellerInfo.class);
mShopSellerInfo.add(shopSellerInfo);
}
mNearBySellerAdapter = new NearBySellerAdapter(getContext(), mShopSellerInfo);
mRecyclerView.setAdapter(mNearBySellerAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
return rootView;`
ShopSellerInfo.java
public ShopSellerInfo(String shopAddress, String shopPhoneNo, String
shopImageUrl, String shopName) {
this.shopAddress = shopAddress;
this.shopPhoneNo = shopPhoneNo;
this.shopImageUrl = shopImageUrl;
this.shopName = shopName;
}
public ShopSellerInfo() {
}
public String getShopAddress() {
return shopAddress;
}
public String getShopPhoneNo() {
return shopPhoneNo;
}
public String getShopImageUrl() {
return shopImageUrl;
}
public String getShopName() {
return shopName;
}
public void setUserAddress(String shopAddress) {
this.shopAddress = shopAddress;
}
public void setUserPhoneNo(String shopPhoneNo) {
this.shopPhoneNo = shopPhoneNo;
}
public void setImageUrl(String shopImageUrl) {
this.shopImageUrl = shopImageUrl;
}
public void setShopName(String shopName) {
this.shopName = shopName;
}
}
This is the structure of my Database
I have a specific node in each unique key the contain data. I want to retrieve that data form every child node and show on single activity.
You're not too far off, just a few mistakes. The following is closer to what you need:
mFirebaseDatabase = FirebaseDatabase.getInstance().getReference("Seller");
mFirebaseDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot sellerSnapshot : dataSnapshot.getChildren()) {
DataSnapshot impInfoSnapshot = sellerSnapshot.child("ImpInfo");
ShopSellerInfo shopSellerInfo = impInfoSnapshot.getValue(ShopSellerInfo.class);
mShopSellerInfo.add(shopSellerInfo);
mNearBySellerAdapter = new NearBySellerAdapter(getContext(), mShopSellerInfo);
mRecyclerView.setAdapter(mNearBySellerAdapter);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException();
}
});
Changes:
Removed the call to .getRef(), which is not needed and in general an anti-pattern.
Removed the call to .child("ImpInfo") from the DatabaseReference, since there is no /Seller/ImpInfo.
Added .child("ImpInfo") in the loop, since you want the ImpInfo child of each snapshot.
Raise an error if onCancelled triggers, since it's a bad practice to ignore errors.

Why am I receiving empty strings after receiving valid data from Firebase?

Using Firebase, I'm trying to display to the user people they have matched with. I already have valid data for testing this and I have already run tests with sample data to see if everything else works.
Now, when I use real data from Firebase, problems occur.
This is what I have for code:
public String username = "";
public String profileImage = "";
public String discussion = "";
private void FetchMatchInformation(final String key, final String choice) {
DatabaseReference matchDb = FirebaseDatabase.getInstance().getReference().child("answers").child(key);
matchDb.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
String opposite = postSnapshot.getValue(String.class);
if(opposite.equals("agree") && choice.equals("disagree")) {
DatabaseReference found = FirebaseDatabase.getInstance().getReference().child("users").child(postSnapshot.getKey());
found.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
if(postSnapshot.getKey().equals("username")) {
username = postSnapshot.getValue(String.class);
}
if(postSnapshot.getKey().equals("providerId")) {
String provider = postSnapshot.getValue(String.class);
if(provider.equals("google.com")) {
Uri photoUrl = FirebaseAuth.getInstance().getCurrentUser().getPhotoUrl();
String originalPieceOfUrl = "s96-c/photo.jpg";
String newPieceOfUrlToAdd = "s400-c/photo.jpg";
String photoPath = photoUrl.toString();
String newString = photoPath.replace(originalPieceOfUrl, newPieceOfUrlToAdd);
profileImage = newString;
} else if(provider.equals("facebook.com")) {
profileImage = FirebaseAuth.getInstance().getCurrentUser().getPhotoUrl().toString() + "?type=large";
}
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
FirebaseDatabase.getInstance().getReference().child("debates").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
if(postSnapshot.getKey().equals(key)) {
discussion = postSnapshot.getValue(String.class);
break;
}
break;
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
MessagesObject objDisc = new MessagesObject(username, discussion, profileImage);
resultsMessages.add(objDisc);
mMessagesAdapter.notifyDataSetChanged();
} else if(opposite.equals("disagree") && choice.equals("agree")) {
DatabaseReference found = FirebaseDatabase.getInstance().getReference().child("users").child(postSnapshot.getKey());
found.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
if(postSnapshot.getKey().equals("username")) {
username = postSnapshot.getValue(String.class);
}
if(postSnapshot.getKey().equals("providerId")) {
String provider = postSnapshot.getValue(String.class);
if(provider.equals("google.com")) {
Uri photoUrl = FirebaseAuth.getInstance().getCurrentUser().getPhotoUrl();
String originalPieceOfUrl = "s96-c/photo.jpg";
String newPieceOfUrlToAdd = "s400-c/photo.jpg";
String photoPath = photoUrl.toString();
String newString = photoPath.replace(originalPieceOfUrl, newPieceOfUrlToAdd);
profileImage = newString;
} else if(provider.equals("facebook.com")) {
profileImage = FirebaseAuth.getInstance().getCurrentUser().getPhotoUrl().toString() + "?type=large";
}
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
FirebaseDatabase.getInstance().getReference().child("debates").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
if(postSnapshot.getKey().equals(key)) {
discussion = postSnapshot.getValue(String.class);
break;
}
break;
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
MessagesObject objDisc = new MessagesObject(username, discussion, profileImage);
resultsMessages.add(objDisc);
mMessagesAdapter.notifyDataSetChanged();
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
So what's happening is I'm getting the user's username, their profile image, and figuring out the value, which I called discussion after determining the valid key. These values are all being accessed from different tree structures from the same real-time database.
Now, at the end of the if or else-if statement, I create and instantiate the MessagesObject by passing in the username, profile image, and discussion variables. I then add this object to the List<MessagesObject> called resultMessages. I then notify my custom adapter mMessagesAdapter that the data has changed.
Like I said, all the other pieces of code work perfectly fine. It's just when I pass username, discussion, and profileImage it always passes an empty string. I know this from using the debugger.
Why is that? It should not be doing that.

How to get all child's data in firebase and show it into my android app?

I have this structure in my Firebase Real-time database :
How can I count the data and show it in my app, which listener shall I use to get all childrens?
There are a few ways in which you could achieve this.
I use the following way:
FirebaseDatabase.getInstance()
.getReference()
.child("demografi")
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnap : dataSnapshot.getChildren()) {
YourObject object = dataSnap.getValue(YourObject.class);
// Use your object as needed
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
dataSnapshot returns the child referenced. Once you have it, all you have to do is iterate through them and you have access to "all children" as you wanted.
FirebaseDatabase.getInstance()
.getReference()
.child("demografi")
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
/** Qty of data in demografi, this is what you want. */
long Count = dataSnapshot.getChildrenCount();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
if you want to monitor the count of data in realtime way,
you have to replace [addListenerForSingleValueEvent] with [addValueEventListener].
I will prefer this way -
String email, gender, nama;
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("demografi");
databaseReference.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
// To get children count
dataSnapshot.getChildrenCount();
email = dataSnapshot.child("email").getValue().toString();
gender = dataSnapshot.child("gender").getValue().toString();
nama = dataSnapshot.child("nama").getValue().toString();
// and so on..
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s){
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
If you don't have a model class, you can simply use the String class. So to get all child's data, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference demografiRef = rootRef.child("demografi");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String nama = ds.child("nama").getValue(String.class);
Log.d("TAG", nama);
}
Log.d("TAG", String.valueOf(dataSnapshot.getChildrenCount()));
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
demografiRef.addListenerForSingleValueEvent(valueEventListener);
The output in your logcat will be all the names of all your users. As you can see, there is a second log statement which will print the total number of your children.

Categories