Only Load Layout When Firebase Calls Are Complete

How to execute success method in Firebase?

Because of the asynchronously behaviour, you need to move the declaration of the assetsLocations ArrayList:

final ArrayList<AssetLocation> assetsLocations = new ArrayList<>();

inside the onDataChange() method, as assetsLocationSpinner ArrayList is. So remember, onDataChange is always called asynchronously. This means that the statement that adds objects of AssetLocation class to the list is executed before onDataChange has been called. That's why your list is empty outside that method.

For other approach, please visit this post and this post.

Hope ot helps.

Layout before Firebase data is loaded

There's a library called Skeleton.

HOW TO USE IT:

Simply use this code when you want the data to load:

mLoading = Skeleton.bind(yourRecyclerView)
.adapter(yourAdapter)
.load(R.layout.your_item) /* This is what you see when loading */
.show();

and then:

FirebaseDatabase.getInstance()
.getReference("yourReference")
.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()){
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
// your code here
}

// Your data is finished loading by now. make sure to call notifyDataSetChanged().
mLoading.hide();
}

}

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

}
});

Continue execution after data received from multiple location in Firebase

I have gone with the Tasks API which Firebase uses already. Its great.

As mentioned by @qbix , This answer does the same thing. The example in the answer explains good.

You can also find video link of this API instructions here.

I have tried and tested it. Solves my problem.

How to check completion of reading from several nodes in Firebase realtime database?

Example if you have two request and you want to run some code after both of them completed and/or succeed:

Boolean ref1done = false;
Boolean ref2done = false;

// if you need data from snapshot
DataSnapshot result1;
DataSnapshot result2;

ref1done = false;
dataRef1.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
ref1done = true;
result1 = dataSnapshot;
doThisAfter();
}
...
});

ref2done = false;
dataRef2.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
ref2done = true;
result2 = dataSnapshot;
doThisAfter();
}
...
});

...

public function doThisAfter() {
if (ref1done && ref2done) {
// do something
// if you need data from snapshot, it can be accessed from result1 and result2
}
}

This might be not the best solution, I'm also still searching if there is a better one. Or maybe you can try using EventBus.

Code does not wait for FirebaseDatabase to be read

As Selvin commented: data is loaded from Firebase asynchronously. You can't reliably wait for the data to become available. See Setting Singleton property value in Firebase Listener.

The solution is to move the code that needs the data from Firebase into the onDataChange in checkDataNew:

fun checkDataNew() {
var rootRef=FirebaseDatabase.getInstance().getReference("BG Data")
// Read from the database
rootRef.addValueEventListener(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
var isKeyFound = false; // local variables
var foundKey;
// This method is called once with the initial value and again
// whenever data at this location is updated.
for(data:DataSnapshot in dataSnapshot.children)
{
var oldEvent=data.child("recentEvent").getValue().toString()
var oldDate:String=data.child("calendarTime").getValue().toString()
var oldEmailID:String=data.child("emailID").getValue().toString()

if(oldEvent.equals(recentEvent) && oldDate.equals(calendarTime) && oldEmailID.equals(emailID)) {
foundKey = data.key.toString()
isKeyFound = true
}
}

// TODO: process the result here
if (isKeyFound) {
...
} else {
...
}
}

override fun onCancelled(error: DatabaseError) {
// Failed to read value
}
})
}

Alternatively you can define your own callback interface, pass that into checkDataNew and invoke it from within there. For an example of this, see getContactsFromFirebase() method return an empty list.

This is a quite common question. So in addition to the links I already provided, I recommend you check out some of these:

  • can't get values out of ondatachange method
  • ArrayList not updating inside onChildAdded function
  • Android Firebase addListenerForSingleValueEvent is not working
  • How to return dataSnapshot value as a result of a method?
  • Only load layout when firebase calls are complete
  • Android: wait for firebase valueEventListener

Getting big data unnecessarily while using orderbychild() from Firebase?

Ordering and filtering data is only done on the Firebase servers if there's an index defined on the property/value you filter on. If there's no index, the server sends all data to the client, which then orders and filters it. There should a quite explicit message in the log output when this happens.

To define an index, you go to the security rules panel in your Firebase console and on the node that myRef points to add an .indexOn property. Say myRef refers to /articles, it'd look something likeL

{
"rules": {
"articles": {
".indexOn": "videoDate"
}
}
}

If you order/filter on different properties, you can add multiple indexes:

".indexOn": [ "videoDate", "category" ]

How do I know if firebase firestore has finished reading data?

The simplest solution would be to add a ProgressBar in your layout file. Assuming you have a ConstraintLayout, you can add it like this:

<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:visibility="gone"/>

And then find it in your activity class like this:

ProgressBar progressBar = findViewById(R.layout.progressBar)

And use it in this way:

progressBar.setVisibility(View.VISIBLE) \\ display it.
DocumentReference df = fstore.collection("Users").document(user.getUid());
df.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
progressBar.setVisibility(View.GONE) \\ hide it.
DocumentSnapshot doc = task.getResult();
if (doc.exists()) {
username.setText("@"+ doc.get("Username").toString());
}
}
}
});


Related Topics



Leave a reply



Submit