FireBase Data Retrieval is getting so much time - android

I am using Firebase to retrieve data and display it on android. At first it was fine but now it is taking 10 sec on addValueUpdateListner anyone know what is the problem?
final String uid1=FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference
dbref1=FirebaseDatabase.getInstance().getReference("users")
.child(uid1)
.child("signUpAs");
dbref1.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
signUpOption=dataSnapshot.getValue(String.class);
Toast.makeText(getBaseContext(),signUpOption,Toast.LENGTH_LONG).show();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});

ValueEventListener retrieves all the data at once so if your database grew up in size, it makes sense to take more time than before.

Related

Retrieve multiple datab by synchronization from Firebase Android

I am trying send my contacts to firebase one by one and checking if the user is present or not but due to the asynchronous behavior of firebase some information is showing twice.
I want to synchronize this method like this:
loop send one number to firebase, firebase response, save, and continue
for (int i=0 ; i< list.size();i++) {
Check_Contact(list.get(i));
}
public void Check_Contact(String number)
{
DatabaseReference myRef = database.getReference("user").child(number);
myRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.getValue() == null) {
}
else {
UserProfile row = dataSnapshot.getValue(UserProfile.class);
ls.add(row);
Adapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Can somebody tell me how to synchronize this method?
Firebase Structure
output coming
It is not the firebase async behaviour. You may have duplicate contents in your database. Please check ur database and update a screenshot of your database in your question.
It will be more helpful to understand your question.

What should i store in the user data in the application and how?

There is the performance issue when i request the Firebase again and again.grid view update very slowly. so what should i do in this case i am thinking to store the path of the posts in the database. is this good idea or to store in the internal storage.(Caching)
private void setuptempGrid(View view){
setupImageGrid(ProfileActivity.images,view);
FirebaseDatabase.getInstance().getReference()
.child(getString(R.string.db_user_posts))
.child(application.getUser().getUserId()).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot d:dataSnapshot.getChildren() ) {
FirebaseDatabase.getInstance().getReference()
.child(getString(R.string.db_posts)).child(getString(R.string.db_public))
.child(d.getKey()).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
gridImageAdapter.add(dataSnapshot.getValue(Posts.class).getProfilePic());
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
I have this code this take to much time to get the images and every time it loads when my fragment is created.
Use
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
Acc. to docs
By enabling persistence, any data that the Firebase Realtime Database client would sync while online persists to disk and is available offline, even when the user or operating system restarts the app. This means your app works as it would online by using the local data stored in the cache.
and also do -
DatabaseReference db = FirebaseDatabase.getInstance().getReference()
.child(getString(R.string.db_user_posts))
.child(application.getUser().getUserId());
db.keepSynced(true);
Use Guava caches as they are optimized and also easy to implement. And before hitting firebase check if you have the data required for the specified node or not.

Android Firebase read data issue

I'm creating an Android app for the first time, I've got a simple Realtime Firebase Database with a couple of records in it. I have the following code;
public void onStart() {
super.onStart();
// Read from the database
databaseMatches.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot matchSnapshot : dataSnapshot.getChildren()) {
matches match = matchSnapshot.getValue(matches.class);
matchesList.add(match);
}
matchList adapter = new matchList (getActivity(), matchesList);
listViewMatch.setAdapter(adapter);
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w(TAG, "Failed to read value.", error.toException());
}
});
If I put a breakpoint on the databaseMatches.addValueEventListener(new ValueEventListener() { it shows me that the database connection has been set and is returning the correct object (In my view).
The challenge I have is the part after, the break points for public void onDataChange nor onCancelled ever get hit. I'm lost here and not sure what might be the next step as it appears to be connecting, but I am not able to retrieve records.
I'm doing this in a fragment instead of a activity. Any help is appreciated.
Detecting Connection State
it is useful for your app to know when it is online or offline. Firebase Realtime Database provides a special location at /.info/connected which is updated every time the Firebase Realtime Database client's connection state changes. Here is an example: If you are not sure.
https://firebase.google.com/docs/database/android/offline-capabilities#section-connection-state
DatabaseReference connectedRef =
FirebaseDatabase.getInstance().getReference(".info/connected");
connectedRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
boolean connected = snapshot.getValue(Boolean.class);
if (connected) {
System.out.println("connected");
} else {
System.out.println("not connected");
}
}
#Override
public void onCancelled(DatabaseError error) {
System.err.println("Listener was cancelled");
}
Firebase also loads and synchronizes data asynchronously
see Setting Singleton property value in Firebase Listener
Thanks.
There must have been some strange caching issue as the following morning when I ran the exact same code, no problem. And I've not had a problem since.

Firebase addValueEventListener excute later in loop

I am using Firebase addValueEventListener to fetch the data from firebase database, below is my code.
DatabaseReference chatMessagesDb = FirebaseDatabase.getInstance().getReference("ChatRooms");
DatabaseReference usersDb = FirebaseDatabase.getInstance().getReference("users");
chatMessagesDb.child(chatRoomId).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot messages : dataSnapshot.getChildren()) {
Message message = messages.getValue(Message.class); // Message is a data Model for chatMessages.
userDb.child(message.getCreatorId()).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
I am applying addValueEventListener on chatMessagesDb and providing a key chatRoomId, so it will fetch all the messages from database of the chatRoom with id equals to chatRoomId. Now, for each message I want to fetch the creator of the Message, so I am adding a addValueEventListener on users database to fetch the details of the creator of a Message.
It should work like, for 1st loop of Message it should call the addValueEventListener on users db for the creator of that message, but it doesn't work like this. First, it loop through all the messages, then it starts calling addValueEventListener on users db.
How can I solve it? Please let me know if anyone have idea about this, this would be a great help.
Thanks a lot in advanced.
I think it's little late to answer, but I think other guys who are learning can be helpful. In case of message from db, use ChildValueEventListener. It returns 4 methods to implement, so any change in the db of a particular node will be listened and return that value.

Should I remove after using "addListenerForSingleValueEvent"

As the document says, listener for SingleValueEvent only run one time.
Then is it unnecessary to remove listener after using it like this?
final Query query = getChatsRef().limitToLast(20);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
query.removeEventListener(this);
}
#Override
public void onCancelled(DatabaseError databaseError) {
query.removeEventListener(this);
}
});
No. Removing the listener as you do in your snippet of code is not needed.
The only reason you might want to remove a once listener, is when the listener hasn't fired yet. The only time I can see that happening is when you're not connected to the Firebase servers and the location you're inspecting is not cached. That should be a fairly small number of cases.

Categories

Resources