i made my app with like button, now i would add the like counter...but i'm confused. you can help me? how can i add the like counter?
i have 2 functions:
first
viewHolder.mLikeBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mProcessLike = true;
if(mProcessLike){
mDatabaseLike.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (mProcessLike) {
if (dataSnapshot.child(post_key).hasChild(mAuth.getCurrentUser().getUid())) {
mDatabaseLike.child(post_key).child(mAuth.getCurrentUser().getUid()).removeValue();
mProcessLike=false;
} else {
mDatabaseLike.child(post_key).child(mAuth.getCurrentUser().getUid()).setValue("RandomValue");
mProcessLike=false;
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
}
second (it's for change the colour of the button)
public void setLikeBtn(final String post_key){
mDatabaseLike.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.child(post_key).hasChild(mAuth.getCurrentUser().getUid())){
mLikeBtn.setImageResource(R.mipmap.likepieno);
}else{
mLikeBtn.setImageResource(R.mipmap.likevuoto);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Related
I have a code for change messageText from database entry:
#Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.edit:
AdapterView.AdapterContextMenuInfo tm = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
int position = tm.position;
final DatabaseReference ref = adapter.getRef(position);
ref.child("messageUserId").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (FirebaseAuth.getInstance().getCurrentUser().getUid().equals(dataSnapshot.getValue().toString())) {
ref.child("messageText").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
input.setText(dataSnapshot.getValue().toString());
sendMessage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ref.child("messageText").setValue(input.getText().toString());
input.getText().clear();
Toast.makeText(Chat.this, "Изменено", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
break;
}
return false;
}
Code ref.child("messageText").setValue(input.getText().toString()) works excellent, but after it code starts up again from
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
input.setText(dataSnapshot.getValue().toString());
And everything goes in a circle - the data from messageText is inserted into the EditText input and I can again change the text.
How to stop executing code after first changing messageText?
ValueEventListener's onDataChange() method:
This method will be called with a snapshot of the data at this location. It will also be called each time that data changes.
With other words, even if it is a write, an update or even a delete operation, this method is triggered. This is also happening in your case, you're using the same reference ref.child("messageText") to add data and also to listen for changes and that's why you have this behaviour. This is happening over and over again. To solve this, you need to change the logic of your code, by creating two different events. onClick to write the data to the database and attach the listener so it cannot be related to that event.
Right code:
#Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.edit:
AdapterView.AdapterContextMenuInfo tm = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
int position = tm.position;
editText = adapter.getRef(position);
editText.child("messageUserId").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (FirebaseAuth.getInstance().getCurrentUser().getUid().equals(dataSnapshot.getValue())) {
editText.child("messageText").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
input.setText(dataSnapshot.getValue().toString());
editMessage();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
} else {
Toast.makeText(Chat.this, "Запрещено", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
return true;
}
private void editMessage() {
sendMessage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
editText.child("messageText").setValue(input.getText().toString());
Toast.makeText(Chat.this, "Изменено", Toast.LENGTH_SHORT).show();
input.getText().clear();
sendMessage();
}
});
}
private void sendMessage() {
sendMessage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (input.getText().toString().trim().equals("")) {
Toast.makeText(Chat.this, getString(R.string.edittext_null), Toast.LENGTH_SHORT).show();
} else {
FirebaseDatabase.getInstance()
.getReference()
.push()
.setValue(new ChatMessage(input.getText().toString(),
Objects.requireNonNull(FirebaseAuth.getInstance().getCurrentUser()).getDisplayName(),
FirebaseAuth.getInstance().getCurrentUser().getUid(),
payload,
avatar,
uploadedAttach
));
input.setText("");
}
}
});
}
It was necessary to simply return to the button its original action and use addListenerForSingleValueEvent instead addValueEventListener.
I want to generate a report pdf counting on total Orders and orders with status wanted
I have this code to create pdf and fill table out
private TemplatePDF templatePDF;
FirebaseDatabase database;
DatabaseReference reference;
Button btnRatio1;
ArrayList<String[]> rowqa=new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reportes);
database=FirebaseDatabase.getInstance();
reference=database.getReference("Requests");
btnRatio1=findViewById(R.id.Quality);
btnRatio1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
reference.orderByChild("date").startAt("1530002755582").endAt("1530504865654").
addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
showData(dataSnapshot);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
createTemplate(rowqa);
}
});
}
private void showData(DataSnapshot dataSnapshot){
int total=(int)dataSnapshot.getChildrenCount();
int count=0;
String[]row;
for (DataSnapshot myDataSnapshot : dataSnapshot.getChildren())
{
Request rq = myDataSnapshot.getValue(Request.class);
if (rq.getStatuscali().equals("0"))
{
count++;
}
}
row= new String[]{Common.getDate(Long.parseLong("1529945980802")),String.valueOf(count),String.valueOf(total),""+ count/total};
addRow(row);
}
private void createTemplate(ArrayList<String[]> rowqa) {
TemplatePDF templatePDF1 = new TemplatePDF(getApplicationContext());
templatePDF1.openDocument("Quality");
templatePDF1.addTitles("Frutifelles E.I.R.L.","Calidad de pedidos generados","25/06/2018");
templatePDF1.createTable(header,rowqa);
templatePDF1.closeDocument();
templatePDF1.viewPDF();
}
private void addRow(String[]row){
rowqa.add(row);
}
The first time show me my pdf this way
But the second time show me correctly
It seems like first time it doesn't work
just as #Jen Person said, you should put the createTemplate(rowqa) inside the onDataChange callback, else when you click the button at the first time, the rowqa is empty, so createTemplate(rowqa) will get an empty PDF.
an example:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reportes);
btnRatio1=findViewById(R.id.Quality);
btnRatio1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// dateStart, dateEnd should be instance fields
queryData(dateStart, dateEnd);
}
});
}
private void queryData(String dateStart, String dateEnd) {
database=FirebaseDatabase.getInstance();
reference=database.getReference("Requests");
reference.orderByChild("date")
.startAt(dateStart)
.endAt(dateEnd)
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
showData(dataSnapshot);
createTemplate(rowqa);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
When a child gets added into my firebase it Logs all the Annotation_City's in my firebase again. How can I get it to only print the new Annotation_City that got added?
public void AllLocationMarkers() {
grabMarkersFromDb = new Firebase("***");
grabMarkersFromDb.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot locationSnapshot : dataSnapshot.getChildren()) {
String city_Name = (String) locationSnapshot.child("Annotation_City").getValue();
Log.d("City updated", "city: " + city_Name);
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
}
grabMarkersFromDb.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
//value add then it will call
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
//value change
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
// value remove
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
use addChildEventListener for it. it will one by one value . and if value is add then its method onChildAdded will call.
read full documentation here.
a2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//below
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
ref.addListenerForSingleValueEvent(new com.google.firebase.database.ValueEventListener() {
#Override
public void onDataChange(com.google.firebase.database.DataSnapshot dataSnapshot) {
ra2 = dataSnapshot.child("a2").getValue(String.class);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
//fetching face value
ref.addListenerForSingleValueEvent(new com.google.firebase.database.ValueEventListener() {
#Override
public void onDataChange(com.google.firebase.database.DataSnapshot dataSnapshot) {
rface = dataSnapshot.child("face").getValue(String.class);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
//fetching nothingdb which is equals to "zero" in Firebase by default.
ref.addListenerForSingleValueEvent(new com.google.firebase.database.ValueEventListener() {
#Override
public void onDataChange(com.google.firebase.database.DataSnapshot dataSnapshot) {
nothing = dataSnapshot.child("nothingdb").getValue(String.class);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
//fetching addeddb which is equals to "one" in Firebase by default.
ref.addListenerForSingleValueEvent(new com.google.firebase.database.ValueEventListener() {
#Override
public void onDataChange(com.google.firebase.database.DataSnapshot dataSnapshot) {
added = dataSnapshot.child("addeddb").getValue(String.class);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
//starting if condition
if (ra2==nothing){
if (rface==nothing){
a2.setBackgroundResource(R.drawable.rounded);{
Firebase refChild = ref2.child("a2");
refChild.setValue("rounda2");
refChild = ref2.child("face");
refChild.setValue("one");
}
else if (rface==added) {
a2.setBackgroundResource(R.drawable.crossed);
{
Firebase refChild = ref2.child("a2");
refChild.setValue("crossa2");
refChild = ref2.child("face");
refChild.setValue("zero");
}
}
}
});
}
});
I am trying to use the above written code so that once I click on the button the background image of the button is changed based on the data present in the Firebase but the If Condition is not working for reason.
It just ignores if (ra2==nothing){ and also the next if conditions.
The listener onDataChange() callbacks are asynchronous. ra2, nothing, added, and rface will not contain valid results when you compare them for equality because the onDataChange() methods will not yet have executed. This answer to a related question explains the execution order in more detail.
In addition, to compare Strings for equality you cannot use the == operator. You must use the equals() method or TextUtils.equals().
#qbix's answer is true, your if condition actually work but it does not receive the value of ra2, rface, nothing, and added yet.
Also, why should you create 4 different ValueEventListener while you listening to the same reference? You can use just 1 listener then put your if condition inside onDataChange, like this:
a2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
ref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
ra2 = dataSnapshot.child("a2").getValue(String.class);
rface = dataSnapshot.child("face").getValue(String.class);
nothing = dataSnapshot.child("nothingdb").getValue(String.class);
added = dataSnapshot.child("addeddb").getValue(String.class);
//starting if condition
if (ra2.equals(nothing)) {
if (rface.equals(nothing)) {
a2.setBackgroundResource(R.drawable.rounded);
Firebase refChild = ref2.child("a2");
refChild.setValue("rounda2");
refChild = ref2.child("face");
refChild.setValue("one");
} else if (rface.equals(added)) {
a2.setBackgroundResource(R.drawable.crossed);
Firebase refChild = ref2.child("a2");
refChild.setValue("crossa2");
refChild = ref2.child("face");
refChild.setValue("zero");
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e(TAG, "onCancelled", databaseError.toException());
}
});
}
});
I have users info as show below
I want to to check if commentWriterUid is equals to one from users key to get its info
I tried this:
Query query = mDatabaseReference_comments.orderByChild("commentWriterUid").equalTo(FirebaseUtil.getUsersReference().getKey());
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
userModel = dataSnapshot.getValue(UserModel.class);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
mFirebaseRecyclerAdapter = new FirebaseRecyclerAdapter<CommentModel, CommentViewHolder>(CommentModel.class,
R.layout.layout_comment,
CommentViewHolder.class,
mDatabaseReference_comments) {
#Override
protected void populateViewHolder(CommentViewHolder viewHolder, CommentModel model, int position) {
Glide.with(PostCommentActivity.this)
.load(userModel.getUserImageUrl())
.into(viewHolder.mCircleImageView_commentWriterImage);
viewHolder.mTextView_commentWriterName.setText(userModel.getUserName());
viewHolder.bindToPost(PostCommentActivity.this, model);
}
};
But I get these errors:
03-04 02:24:34.558 31063-31063/com.app E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.NullPointerException
at com.app.PostCommentActivity$4.populateViewHolder(PostCommentActivity.java:119)
at com.app.PostCommentActivity$4.populateViewHolder(PostCommentActivity.java:113)
No one answer my question so i figured it my own and answer this so it may be helpful for others
FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance();
final DatabaseReference root_ref = firebaseDatabase.getReference();
root_ref.child("comments").child("KeKwGa5btKuDYr3yYq5").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String commentWriterUid = dataSnapshot.child("commentWriterUid").getValue().toString();
root_ref.child("users").equalTo(commentWriterUid).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Do all stuff you went
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});