I have a an app with a functioning Next question button to proceed to the next question but I am having a problem when coding the "previous question" button.
I have coded it the same as the "next question" except that instead of incrementing (i++) I just decrement it (i--)
It does its job and it returns to the previous question...
But! when I press the previous button it does this.
example: I'm at question 4 and pressed previous, it goes to question 5 then if I click previous again it then goes back to question 4 and if I clicked it again then it will be a normal previous button. The same will also happen if I pressed previous then clicked next again but only in reverse.
NEXT QUESTION CODE
question = new Firebase("https://thesis-e4f56-default-rtdb.firebaseio.com/Set1/" + questionNumber + "/question");
question.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String question = dataSnapshot.getValue(String.class);
mQuestion.setText(question);
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
questionum = new Firebase("https://thesis-e4f56-default-rtdb.firebaseio.com/Set1/" + questionNumber + "/num");
questionum.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String question = dataSnapshot.getValue(String.class);
nQuestion.setText(question);
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
c1 = new Firebase("https://thesis-e4f56-default-rtdb.firebaseio.com/Set1/" + questionNumber + "/choice1");
c1.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String choice = dataSnapshot.getValue(String.class);
choice1.setText(choice);
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
c2 = new Firebase("https://thesis-e4f56-default-rtdb.firebaseio.com/Set1/" + questionNumber + "/choice2");
c2.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String choice = dataSnapshot.getValue(String.class);
choice2.setText(choice);
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
c4 = new Firebase("https://thesis-e4f56-default-rtdb.firebaseio.com/Set1/" + questionNumber + "/choice4");
c4.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String choice = dataSnapshot.getValue(String.class);
choice4.setText(choice);
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
c5 = new Firebase("https://thesis-e4f56-default-rtdb.firebaseio.com/Set1/" + questionNumber + "/choice5");
c5.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String choice = dataSnapshot.getValue(String.class);
choice5.setText(choice);
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
// answer = new Firebase( "https://thesis-e4f56-default-rtdb.firebaseio.com/"+questionNumber+"/answer");
// answer.addValueEventListener(new ValueEventListener() {
// #Override
// public void onDataChange(DataSnapshot dataSnapshot) {
// ans = dataSnapshot.getValue(String.class);
// }
// #Override
// public void onCancelled(FirebaseError firebaseError) {
// }
// });
if (questionNumber == 10) {
Intent intent = new Intent(depression_assessment.this, schoolwork_assessment.class);
startActivity(intent);
String Score = mScoreView.getText().toString();
// root.push().setValue(Score);
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Score");
ref.child(userId).child("result_general").setValue(Score);
}
// gameWon();
// storeScore();
questionNumber++;
if (questionNumber <=2) {
prev.setVisibility(View.VISIBLE);
}
if (questionNumber ==1) {
prev.setVisibility(View.INVISIBLE);
}
}
PREVIOUS QUESTION CODE
question = new Firebase("https://thesis-e4f56-default-rtdb.firebaseio.com/Set1/" + questionNumber + "/question");
question.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String question = dataSnapshot.getValue(String.class);
mQuestion.setText(question);
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
questionum = new Firebase("https://thesis-e4f56-default-rtdb.firebaseio.com/Set1/" + questionNumber + "/num");
questionum.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String question = dataSnapshot.getValue(String.class);
nQuestion.setText(question);
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
c1 = new Firebase("https://thesis-e4f56-default-rtdb.firebaseio.com/Set1/" + questionNumber + "/choice1");
c1.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String choice = dataSnapshot.getValue(String.class);
choice1.setText(choice);
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
c2 = new Firebase("https://thesis-e4f56-default-rtdb.firebaseio.com/Set1/" + questionNumber + "/choice2");
c2.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String choice = dataSnapshot.getValue(String.class);
choice2.setText(choice);
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
c4 = new Firebase("https://thesis-e4f56-default-rtdb.firebaseio.com/Set1/" + questionNumber + "/choice4");
c4.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String choice = dataSnapshot.getValue(String.class);
choice4.setText(choice);
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
c5 = new Firebase("https://thesis-e4f56-default-rtdb.firebaseio.com/Set1/" + questionNumber + "/choice5");
c5.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String choice = dataSnapshot.getValue(String.class);
choice5.setText(choice);
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
// gameWon();
// storeScore();
questionNumber--;
}
You increase the question number at the very last, that's the issue.
For example, let's say you loaded data of question 3, the index will now show question 4, your previous button will load question 4 THEN will decrement the index
Instead, the questionnumber must initiated at -1 (because 0 will be the first question index). Then the questionnumber++ must be the very first thing to do on code.
The same about questionnumber-- for the previous button.
This, the questionnumber will indicate the current question (you can do a +1 to show it to the user for a human readable), and it will not hold the next future question instead you have here.
Related
Hi I want to read the display data from RecyclerView and make comparison.
This my layout for the activity:
What I want to do is to read all data from RecyclerView and compare with Daily Calorie Suggestion.
After reading all data, I need to make comparisons on how many times the user have taken above, less or sufficient total calories as shown in the "Analysis of Total Calories Consumed of Last 7 Days"
The code:
#Override
protected void onStart() {
Query query = ref.orderByChild("timeStamp").limitToLast(7).endAt(Date);
super.onStart();
if (query != null) {
query .addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
userHighlights = new ArrayList<>();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
userHighlights.add(ds.getValue(HighightsModel.class));
requiredCalorieRef = FirebaseDatabase.getInstance().getReference("Users").child(FirebaseAuth.getInstance().getCurrentUser().getUid());
requiredCalorieRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String userCalorieSuggestion = String.valueOf((dataSnapshot.child("daily calorie").getValue()));
int daily_calorie = Integer.parseInt(userCalorieSuggestion);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
HighlightsAdapter highlightsAdapter = new HighlightsAdapter(userHighlights);
highlightsRV.setAdapter(highlightsAdapter);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(UserNewHighlights.this, databaseError.getMessage(),
Toast.LENGTH_SHORT).show();
}
});
}
}
This is my firebase:
Do I have to write a new code to solve this problem or else? Any help will be much appreciated. Thanks
As #MasoudDarzi mentioned, it's not related to the RecyclerView.
You can try something like this:
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
userHighlights = new ArrayList<>();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
userHighlights.add(ds.getValue(HighightsModel.class));
requiredCalorieRef = FirebaseDatabase.getInstance().getReference("Users").child(FirebaseAuth.getInstance().getCurrentUser().getUid());
requiredCalorieRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String userCalorieSuggestion = String.valueOf((dataSnapshot.child("daily calorie").getValue()));
int daily_calorie = Integer.parseInt(userCalorieSuggestion);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
HighlightsAdapter highlightsAdapter = new HighlightsAdapter(userHighlights);
highlightsRV.setAdapter(highlightsAdapter);
// do calculation here with userHighlights
int countExceeded = 0, countBelow = 0, countSufficient = 0;
for (HighightsModel h : userHighlights) {
if (h.totalCalorie > daily_calorie) {
countExceeded++;
} else if (h.totalCalorie < daily_calorie) {
countBelow++;
} else {
countSufficient++;
}
}
// update your TextView with the count numbers
// todo
}
}
so The brute force solution is to have a for in your data after getting the 7 days average.
for (your 7 days data){
// check if your data is lower or higher than the average
// and store number of higher or lower
}
looking for a better solution?
I have solved my problem by adding another child at History node. Whereby, previously I have only these for History :
but I add new child which is called STATUS, the status is updated from previous activity as seen the pic below:
so what I did for the code is :
private void upDateAnalysisAbove() {
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("History");
DatabaseReference mRef = ref.child(FirebaseAuth.getInstance().getCurrentUser().getUid());
Query mQuery = mRef.orderByChild("status").equalTo("ABOVE").limitToLast(7);
mQuery.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String value = String.valueOf(dataSnapshot.getChildrenCount());
int values = Integer.parseInt(value);
txt_above_output.setText(values + " times(s)");
upDateAnalysisLess(values);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
//LESS
private void upDateAnalysisLess(int values) {
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("History");
DatabaseReference mRef = ref.child(FirebaseAuth.getInstance().getCurrentUser().getUid());
Query mQuery = mRef.orderByChild("status").equalTo("LESS").limitToFirst(7);
mQuery.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String valueLess = String.valueOf(dataSnapshot.getChildrenCount());
int values_Less = Integer.parseInt(valueLess);
if (values_Less == 0){
txt_less_output.setText(values_Less + " times(s)");
}
if (values > values_Less){
int finalCount = values - values_Less ;
txt_less_output.setText(finalCount + " times(s)");
}
if (values <values_Less){
int finalCount = values_Less - values ;
txt_less_output.setText(finalCount + " times(s)");
}
updateSuff();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
//SUFFICIENT
private void updateSuff() {
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("History");
DatabaseReference mRef = ref.child(FirebaseAuth.getInstance().getCurrentUser().getUid());
Query mQuery = mRef.orderByChild("status").equalTo("SUFFICIENT").limitToFirst(7);
mQuery.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String value = String.valueOf(dataSnapshot.getChildrenCount());
int suffValue = Integer.parseInt(value);
if (suffValue == 0) {
txt_sufficient_output.setText(suffValue + " times(s)");
}
if (suffValue != 0){
txt_sufficient_output.setText(suffValue + " times(s)");
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Here is the output:
credit to this post that helped me a lot, and thanks for those who tried to help me.
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
I want to connect the user id with the same key in Users, then show the key to FirebaseRecyclerAdapter. I get the key in Friend child already but don't know how to match this to Users.
And my code:
mFriendList = FirebaseDatabase.getInstance().getReference().child("Friends").child(current_id);
mFriendDatabase = FirebaseDatabase.getInstance().getReference().child("Users");
mFriendList.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
String sd = snapshot.getKey(); //key from Friends
final FirebaseRecyclerAdapter<Users_Friends, UsersFriendViewHolder> firebaseRecyclerAdapter =
new FirebaseRecyclerAdapter<Users_Friends, UsersFriendViewHolder>(
Users_Friends.class,
R.layout.users_single_friend_layout,
UsersFriendViewHolder.class,
filter
) {
#Override
protected void populateViewHolder(UsersFriendViewHolder viewHolder, Users_Friends users, int position) {
viewHolder.setDisplayName(users.getName());
viewHolder.setStatusUsers(users.getStatus());
viewHolder.setUserImage(users.getImage(), getContext().getApplicationContext());
final String user_id = getRef(position).getKey();
viewHolder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent profileIntent = new Intent(getActivity(), ProfileActivity.class);
profileIntent.putExtra("user_id", user_id);
startActivity(profileIntent);
}
});
}
};
mReqList.setAdapter(firebaseRecyclerAdapter);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
You only need to use exists() method directly on the dataSnapshot object like this:
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.child(current_id).exists()) {
Log.d("TAG", "User exists");
} else {
Log.d("TAG", "User does not exist");
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
mFriendDatabase.addListenerForSingleValueEvent(eventListener);
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
}
});
this.books = new ArrayList<>();
mFirebaseDatabaseReference.child(SellBooksPost).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange( DataSnapshot AdataSnapshot) {
for (final DataSnapshot AmessageSnapshot : AdataSnapshot.getChildren()) {
bFirebaseDatabaseReference.child(mUserId).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot BdataSnapshot) {
for (DataSnapshot BmessageSnapshot : BdataSnapshot.getChildren()) {
if (BmessageSnapshot.child("book").getValue().toString().equals(AmessageSnapshot.child("SellBooksPostId").getValue().toString())){
Log.d("INFO", "SELL BOOK book " + BmessageSnapshot.child("book").getValue());
Log.d("INFO", "SELL BOOK DETAIL " + AmessageSnapshot.child("SellBooksPostId").getValue());
books.add(new Book(
AmessageSnapshot.child("SellBooksPostId").getValue().toString(),
AmessageSnapshot.child("bookTitle").getValue().toString()
));
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
saleBookPostAdapter = new SaleBookPostAdapter(getApplicationContext(), books);
mRoomRecyclerView.setHasFixedSize(true);
mRoomRecyclerView.setAdapter(saleBookPostAdapter);
It's hard to say if this is a problem, but I do not see a call to RecyclerView.Adapter#notifyDataSetChanged() method after updating the data. So try call
salesBookAdapter.notifyDataSetChanged()
after
books.add(new Book(
AmessageSnapshot.child("SellBooksPostId").getValue().toString(),
AmessageSnapshot.child("bookTitle").getValue().toString()
));