I have just started using Android and Firebase. I have built a simple test Firebase database and I want to run a simple query.
If I use ChildEventListener, I get reasonable results and code for that looks like this:-
Query query = databaseReference.orderByChild("calendarGroup").equalTo("2");
mChildEventListner = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
CalendarEntry calendarEntry = dataSnapshot.getValue(CalendarEntry.class);
linesToDisplay = linesToDisplay + "\n" + calendarEntry.getCalendarDate() +
", " + calendarEntry.getCalendarEntry() +
", " + calendarEntry.getCalendarGroup();
resultText.setText(linesToDisplay);
}
#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) {
Toast mToast = Toast.makeText(getApplicationContext(), "Error", Toast.LENGTH_SHORT);
mToast.show();
;
}
};
query.addChildEventListener(mChildEventListner);
But as this is a single event query, I wanted to do that using SingleValueListener. It doesn't work (I get null values), The code is below:-
Query query = databaseReference.orderByChild("calendarGroup").equalTo("2");
ValueEventListener mValueEventListener;
mValueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
CalendarEntry calendarEntry = dataSnapshot.getValue(CalendarEntry.class);
linesToDisplay = linesToDisplay + "\n" + calendarEntry.getCalendarDate() +
", " + calendarEntry.getCalendarEntry() +
", " + calendarEntry.getCalendarGroup();
resultText.setText(linesToDisplay);
}
#Override
public void onCancelled (DatabaseError databaseError){
}
};
query.addListenerForSingleValueEvent(mValueEventListener);
What am I doing wrong?
Please do this:
mValueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot data : dataSnapshot.getChildren()){
CalendarEntry calendarEntry = data.getValue(CalendarEntry.class);
linesToDisplay = linesToDisplay + "\n" + calendarEntry.getCalendarDate() +
", " + calendarEntry.getCalendarEntry() +
", " + calendarEntry.getCalendarGroup();
resultText.setText(linesToDisplay);
}
}
#Override
public void onCancelled (DatabaseError databaseError){
}
};
query.addListenerForSingleValueEvent(mValueEventListener);
Please add the for loop to be able to retrieve the data.
In ValueEventListener you have to loop inside the node which is different that the childeventlistener where it is able to get the values without looping.
Related
First of all, I'm a real beginner in Android and want to learn.
I want to rate a user who responded to my initiated message using firebase. So only once can the user who initiated the conversation
rate the other user, but only after the response ( first response, no matter what response, even if it is just "hi")
He can receive any amount of ratings (positive or negative) but from different users), in my case, I add/subtract 10 for every vote.
My Firebase DB structure looks like this:
Layout:
I have tried this way, but haven't succeeded:
if (FirebaseAuth.getInstance().getCurrentUser() != null) {
messageRef = mRootRef.child("messages")
.child(mCurrentUserId)
.child(mChatUser);
chatRef = mRootRef.child("chat")
.child(mCurrentUserId)
.child(mChatUser);
final Query convQuery = chatRef;
convQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Conv conversation = dataSnapshot.getValue(Conv.class);
convVoted = conversation.isVoted();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Query messageCheckQuery = messageRef.orderByKey();
messageCheckQuery.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Messages message = dataSnapshot.getValue(Messages.class);
final String messageKey = dataSnapshot.getKey();
String messageTo = message.getTo();
voteBoolean = message.isVoted();
if (!messageTo.equals(mCurrentUserId)) {
ratingLayout.setVisibility(View.GONE);
} else {
if (!convVoted) {
ratingLayout.setVisibility(View.VISIBLE);
Query query = mRootRef.child("user_account_settings")
.orderByKey()
.equalTo(mChatUser);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
DataSnapshot singleSnapshot = dataSnapshot.getChildren().iterator().next();
UserInfo userInfo = singleSnapshot.getValue(UserInfo.class);
voteNumberStr = userInfo.getMessage_rating();
Log.d("RATING", " Voted : " + convVoted + " | Rating Number : " + voteNumberStr);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
mVoteUpBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
voteNumber = Integer.parseInt(voteNumberStr);
voteNumber = voteNumber + 10;
voteNumberStr = String.valueOf(voteNumber);
convVoted = true;
//voteBoolean = true;
mRootRef.child("messages")
.child(mCurrentUserId)
.child(mChatUser)
.child(messageKey)
.child("voted").setValue(true);
mRootRef.child("chat")
.child(mCurrentUserId)
.child(mChatUser)
.child("voted").setValue(true);
mRootRef.child("user_account_settings")
.child(mChatUser)
.child("message_rating").setValue(voteNumberStr);
Log.d("RATING", " clicked : " + convVoted + " | Rating Number : " + voteNumberStr);
ratingLayout.setVisibility(View.GONE);
}
});
mVoteDownBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
voteNumber = voteNumber - 10;
voteNumberStr = String.valueOf(voteNumber);
//voteBoolean = true;
convVoted = true;
mRootRef.child("messages")
.child(mCurrentUserId)
.child(mChatUser)
.child(messageKey)
.child("voted").setValue(true);
mRootRef.child("chat")
.child(mCurrentUserId)
.child(mChatUser)
.child("voted").setValue(true);
mRootRef.child("user_account_settings")
.child(mChatUser)
.child("message_rating").setValue(voteNumberStr);
Log.d("RATING", " clicked : " + convVoted + " | Rating Number : " + voteNumberStr);
ratingLayout.setVisibility(View.GONE);
}
});
} else
{
ratingLayout.setVisibility(View.GONE);
}
}
}
#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) {
}
});
}
ANY HELP WOULD BE MUCH APPRECIATED.
if i understood your problem i do this way, i perform the rating only on message click, i think is the best way.
remove the bottom rate.
eg
While retrieving the data I am using this code
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot data : dataSnapshot.getChildren()) {
Firebasemodel firebasemodel = data.getValue(Firebasemodel.class);
firebasemodels.add(firebasemodel);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});`
This code snippet which returns the complete data of firebase database.
But I want to retrieve the complete data of particular users. How do I achieve it?
Thanks in advance
Try code below:
FirebaseDatabase.getInstance().getReference().child("notepad-secure/notepad").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Iterator<DataSnapshot> dataSnapshots = dataSnapshot.getChildren().iterator();
while (dataSnapshots.hasNext()) {
user = dataSnapshotChild.getValue(User.class);
users_list.add(user);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d("Error", "---" + databaseError.getMessage());
}
});
Model class:
public class User {
public String id;
public String note;
public String tittle;
public User() {
}
public User(String id, String note, String tittle) {
this.id= id;
this.note= note;
this.tittle= tittle;
}
}
And Declare
List<User> users_list;
User user;
Please use this code for getting all data:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference notepadRef = rootRef.child("notepad-secure").child("notepad");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String id = ds.child("id").getValue(String.class);
String note = ds.child("note").getValue(String.class);
String title = ds.child("title").getValue(String.class);
String user = ds.child("user").getValue(String.class);
Log.d("TAG", id + " / " + note + " / " + title + " / " + users);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
notepadRef.addListenerForSingleValueEvent(eventListener);
And your output will be:
-Kono2LMSe... / sadsad / sadsad / NK46X......
If you want to retrieve only specific data, please use this code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference notepadRef = rootRef.child("notepad-secure").child("notepad").child("NK46...");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String id = ds.child("id").getValue(String.class);
String note = ds.child("note").getValue(String.class);
String title = ds.child("title").getValue(String.class);
String user = ds.child("user").getValue(String.class);
Log.d("TAG", id + " / " + note + " / " + title + " / " + users);
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
notepadRef.addListenerForSingleValueEvent(eventListener);
It will work for sure.
I'm trying to send a query on database to display the associated node number if it matches with the string 'token' inputed by the user. However, I'm getting a 'Method does not override method from its superclass' and 'Method onCancelled is never used in method' just for the onCancelled function. Where am I going wrong?
buttonSave.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Creating firebase object
Firebase ref = new Firebase(Config.FIREBASE_URL);
//Getting values to store
String token = editToken.getText().toString().trim();
Query query = ref.orderByChild("token").equalTo(token, "token");
query.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot snapshot, String previousChildKey) {
Person user = snapshot.getValue(Person.class);
String demo=user.getNodes();
System.out.println("Nodes: " + demo);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
Person friend = dataSnapshot.getValue(Person.class);
Toast.makeText(enter_page.this
, "Friend removed: " + dataSnapshot.getKey()
+ " token: " + friend.getToken()
+ " name: " + friend.getNodes()
, Toast.LENGTH_SHORT).show();
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
Person friend = dataSnapshot.getValue(Person.class);
Toast.makeText(enter_page.this
, "Friend changed: " + dataSnapshot.getKey()
+ " token: " + friend.getToken()
+ " nodes: " + friend.getNodes()
, Toast.LENGTH_SHORT).show();
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
System.out.println("DATABASE ERROR");
}
});
OnCanceled uses a FirebaseError and not a DatabaseError so it should be like this :
#Override
public void onCancelled(FirebaseError databaseError) {
System.out.println("DATABASE ERROR");
}
Parameters types are important when overriding a method.
My Firebase Database is look like as bellow:
I want to show an error message when email val is not available in firebase database.
And my code is
mRef.orderByChild("email").equalTo(val).addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
User user = dataSnapshot.getValue(User.class);
textView.setText("Welcome " + user.name );
System.out.println(user.name + "\n" + user.email + "\n" + user.tell);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
User user = dataSnapshot.getValue(User.class);
textView.setText("Welcome " + user.name );
System.out.println(user.name + "\n" + user.email + "\n" + user.tell);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
A ChildEventListener can only detect the presence of a certain child node or when a child node is changed/removed. It cannot detect the absence of a child. To detect that there is no value, you need a ValueEventListener:
mRef.orderByChild("email").equalTo(val).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.getChildrenCount() == 0) {
System.out.println("No user with email "+val);
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
throw firebaseError.toException(); // don't ignore onCancelled!
}
});
mQuery = databaseReference.limitToLast(1).orderByChild("email").equalTo(category);
mQuery.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.i(TAG, "onDataChange: "+dataSnapshot.toString());
GenericTypeIndicator<Map<String,UserModel>> t=new GenericTypeIndicator<Map<String,UserModel>>(){};
try{
Map<String,UserModel> userList=dataSnapshot.getValue(t);
}catch(Exception exception){
//Error UserInfo not present in firebase
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
//Error wile accessing database
}
});
Hi I was trying firebase with , My server has around 300 records which is getting synced with my app in 3 to four minutes in single, single way
cant it be like get record in set of 50 or something ??
If user is coming online after very long time then also I need this batching.
If user is installing app first time then also i need to download bulk record from firebase database
I am using
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.e(TAG, "addListenerForSingleValueEvent:onDataChange" + dataSnapshot.getValue());
reference.removeEventListener(valueEventListener);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e(TAG, "addListenerForSingleValueEvent:onCancelled" + databaseError.getMessage());
}
};
and
public class DBService extends Service {
private static final String TAG = DBService.class.getName();
private StartApplication application;
private ObjectMapper objectMapper;
#Override
public void onCreate() {
super.onCreate();
application = ((StartApplication) getApplication());
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference reference = database.getReference();
objectMapper = new ObjectMapper();
ChildEventListener childEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
try {
String json = objectMapper.writeValueAsString(dataSnapshot.getValue());
Job job = objectMapper.readValue(json, Job.class);
ContentValues values = ContentValuesParser.parseJobs(job);
Uri uri = getContentResolver().insert(TableContract.JobsEntry.CONTENT_URI, values);
Log.d(TAG, "child add id " + job.getId() + " Uri " + uri.getEncodedPath());
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
}
//Uri uri = getContentResolver().insert(TableContract.JobsEntry.CONTENT_URI, values);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
try {
String json = objectMapper.writeValueAsString(dataSnapshot.getValue());
Job job = objectMapper.readValue(json, Job.class);
ContentValues values = ContentValuesParser.parseJobs(job);
Uri uri = getContentResolver().insert(TableContract.JobsEntry.CONTENT_URI, values);
Log.d(TAG, "child changed id " + job.getId() + " Uri " + uri.getEncodedPath());
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
}
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
reference.child("jobs").addChildEventListener(childEventListener);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}}
Have you tried Querying data?
Query queryRef = ref.orderByChild("weight").limitToLast(50);
//This will fetch the last 50 children.
queryRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot snapshot, String previousChild) {
System.out.println(snapshot.getKey());
}