Hopefully someone can help me with this. Lets say I have a post and I want to track down the number of clicks it gets. How do I go about incrementing the value in the database (Firebase). For example the post has one click that count as 1 then it has another click that counts as 2 then so on and so fourth. I tried doing something but I'm getting this error. I really need your help on this. Thanks in advance
Error message
Can't convert object of type java.lang.Long to type com.myapp.poopy.Model_Information
My code
databaseReference = FirebaseDatabase.getInstance("https://poopy-43981.firebaseio.com/").getReference().child("Post").child(getid);
int count;
count = count ++;
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
databaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
databaseReference.child("clicks").setValue(count+1);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
});
Json
{
"Post" : {
"lG71ennq86UIZ5a5Oqh8oaYAXe03" : {
"-MHNWmVK3rBnvnr0qcph" : {
"clicks" : 0,
"id" : "-MHNWmVK3rBnvnr0qcph",
}
}
},
Model_class
public Model_Information(String category, String headline, String mImageUrl,String created,String time,String id,String status ) {
this.mImageUrl = mImageUrl;
this.category = category;
this.headline = headline;
this.created=created;
this.time=time;
this.id=id;
this.status=status;
}
public Model_Information() {
}
public String getstatus() {
return status;
}
public void setstatus(String status) {
status = status;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getCreated() {
return created;
}
public void setCreated(String created) {
this.created = created;
}
public String getmImageUrl() {
return mImageUrl;
}
public void setmImageUrl(String mImageUrl) {
this.mImageUrl = mImageUrl;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getHeadline() {
return headline;
}
public void setHeadline(String headline) {
this.headline = headline;
}
//Class using model class
databaseReference.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String previousChildName) {
if (dataSnapshot.exists()) {
progressBar.setVisibility(View.GONE);
for (DataSnapshot postsnapshot : dataSnapshot.getChildren()) {
myUploads.clear();
Model_Information upload = postsnapshot.getValue(Model_Information.class);
myUploads.add(upload);
aAdapter = new Adapter(MainActivity2.this, myUploads);
recyclerView.setAdapter(aAdapter);
aAdapter.notifyDataSetChanged();
recyclerView.invalidate();
}
}
}
To be able to update the clicks value you need to know the complete path to that value. In your use-case there seem to be two variables in that path:
the UID
a push ID
Once you know both values, increment the value can be done with the (relatively new) ServerValue.increment operation like this:
DatabaseReference rootReference = FirebaseDatabase.getInstance("https://poopy-43981.firebaseio.com/");
DatabaseReference userReference = rootReference.child("Post").child(getid);
DatabaseReference countReference = userReference.child("-MHNWmVK3rBnvnr0qcph").child("clicks");
countReference.setValue(ServerValue.increment(1));
Related
I am developing an android application using Firebase Realtime Database. But I get Null Object every time. I am getting value in a Static Object, declare and Initialize in a Common class which extends the Application class;
This is my database Structure
Here Is my Code for fetching data
void getLicRequest(String iid)
{
DatabaseReference ref= FirebaseDatabase.getInstance().getReference("LicenseUpRequests");
Query qu=ref.orderByChild("id").equalTo(iid);
qu.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
Commons k=(Commons)getApplicationContext();
k.licRequest=snapshot.getValue(LicenseModel.class);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
```
This is my Model Class
public class LicenseModel {
public String frontSide;
public String backSide;
public String id;
public String date;
public String getFrontSide() {
return frontSide;
}
public void setFrontSide(String frontSide) {
this.frontSide = frontSide;
}
public String getBackSide() {
return backSide;
}
public void setBackSide(String backSide) {
this.backSide = backSide;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
}
```
When you execute a query against the Firebase Database, there will potentially be multiple results. So the snapshot contains a list of those results. Even if there is only a single result, the snapshot will contain a list of one result.
Your onDataChange will need to navigate this list, by looping over snapshot.getChildren():
qu.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
Commons k=(Commons)getApplicationContext();
for (DataSnapshot requestSnapshot: snapshot.getChildren()) {
k.licRequest=requestSnapshot.getValue(LicenseModel.class);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException(); // Never ignore errors
}
});
This is the structure of data from my firebase:
I have problem to retrieve all "menukedai" data. By using the code below, data from "menukedai" didnt come out. For your information, the data of "menukedai" will come from the user.
This is my attempt:
foodDatabaseRef = FirebaseDatabase.getInstance().getReference("uploads").child("menukedai");
foodDatabaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
foodmenu foodmenu = postSnapshot.getValue(foodmenu.class);
fooddata.add(foodmenu);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(foodlist.this, databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
This is my foodmenu class.
package com.example.trialfoodbuddy;
public class foodmenu {
private String Foodimage;
private String Foodname;
private CharSequence Foodprice;
public foodmenu(){
//empty constructor needed
}
public foodmenu(String foodimage, String foodname, CharSequence foodprice){
Foodimage = foodimage;
Foodname = foodname;
Foodprice = foodprice;
}
public String getFoodimage(){
return Foodimage;
}
public String getFoodname(){
return Foodname;
}
public CharSequence getFoodprice(){
return Foodprice;
}
public void setFoodimage(String foodimage){
Foodimage = foodimage;
}
public void setFoodname(String foodname){
Foodname = foodname;
}
public void setFoodprice(CharSequence foodprice){
Foodprice = foodprice;
}
}
I Believe you want to get the information nested under "menukedai" so you will need to add another loop for that information
foodDatabaseRef = FirebaseDatabase.getInstance().getReference("uploads");
foodDatabaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot uploadSnapshot : dataSnapshot.getChildren()) {
// this is where you actually getting the information
for(DataSnapshot menuItemSnapshot : uploadSnapshot.child("menukedai").getChildren()){
foodmenu foodmenu = menuItemSnapshot.getValue(foodmenu.class);
fooddata.add(foodmenu);
}
}
}
// Log the values and check them to make sure you getting the data you want if always nice so I added it for you here
Log.i("Values","My values are:"+foodmenu);
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(foodlist.this, databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
Normally speaking, You should always use the variable names in your class in your Database so when you pulling the information, your constructor would know what value assign to which variable in your class.
I want to show if a message is seen or not in my app which is using Firebase Real time Database.What i am able to till now is update it on on the database if the message is seen or not but i am not able to retrieve that value using listeners in my recyclerview Adaptor .It happens that if the last message is not seen it displays all the previous messages are not seen similarly if the last message is seen it displays all the previous messages are seen.
Database Structure
My Code for checking if the message is seen or not
#Override
public void onBindViewHolder(#NonNull MessageAdapter.ViewHolder holder, int position) {
Chat chat=mChat.get(position);
holder.show_message.setText(chat.getMessage());
if (Key != null) {
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("Chats").child(ChatKey).child(Key);
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
Chat chat1 = dataSnapshot.getValue(Chat.class);
if (chat1.isIsseen()) {
holder.Delivered.setImageResource(R.drawable.ic_done_all_black_24dp);
} else {
holder.Delivered.setImageResource(R.drawable.ic_check_black_24dp);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
};
databaseReference.addValueEventListener(eventListener);
}
if (imageurl.equals("default")){
holder.profile_image.setImageResource(R.drawable.user2);
} else {
Glide.with(mContext).load(imageurl).into(holder.profile_image);
}
}
Update
Chat Class
public class Chat {
private String sender;
private String receiver;
private String message;
private boolean isseen;
private long timestamp;
String MessageId;
public Chat(String sender, String receiver, String message, boolean isseen, long timestamp) {
this.sender = sender;
this.receiver = receiver;
this.message = message;
this.isseen = isseen;
this.timestamp = timestamp;
}
public Chat() {
}
public String getSender() {
return sender;
}
public void setSender(String sender) {
this.sender = sender;
}
public String getReceiver() {
return receiver;
}
public void setReceiver(String receiver) {
this.receiver = receiver;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getMessageId() {
return MessageId;
}
public void setMessageId(String messageId) {
MessageId = messageId;
}
public boolean isIsseen() {
return isseen;
}
public void setIsseen(boolean isseen) {
this.isseen = isseen;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
}
Update2
isseen Listener
private void seenMessage(final String userid){
reference = FirebaseDatabase.getInstance().getReference("Chats").child(ChatKey);
// reference.keepSynced(true);
seenListener=new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Chat chat = snapshot.getValue(Chat.class);
if (chat.getReceiver().equals(fuser.getUid()) && chat.getSender().equals(userid)) {
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("isseen", true);
snapshot.getRef().updateChildren(hashMap);
}
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
};
reference.addListenerForSingleValueEvent(seenListener);
}
Do this in onBindViewHolder
#Override
public void onBindViewHolder(#NonNull MessageAdapter.ViewHolder holder, int position) {
Chat chat=mChat.get(position);
holder.show_message.setText(chat.getMessage());
boolean isSeen = chat.isIsseen();
if(isSeen){
//seen
holder.Delivered.setImageResource(R.drawable.ic_done_all_black_24dp);
}else{
//not seen
holder.Delivered.setImageResource(R.drawable.ic_check_black_24dp);
}
if (imageurl.equals("default")){
holder.profile_image.setImageResource(R.drawable.user2);
} else {
Glide.with(mContext).load(imageurl).into(holder.profile_image);
}
}
UPDATE:
If you want to refresh the recycler view for live updates add this method under the onBindViewHolder():
#Override
public void onDataChanged() {
//refresh
yourAdapter.notifyDataSetChanged();
}
I have a chat app and I'm trying to pull down the chat groups that the logged in user is part of. I'm struggling to get down the right groups. Here is my firebase structure. All the members are under the "members" child inside a group. I'm displaying the groups in a recyclerview that works fine. This has of course work for any user that logs in and a user can be part of many different groups. I hope you get the idea and can help me. Thanks
My code:
private FirebaseDatabase mDatabase;
private DatabaseReference mDatabaseReference;
private FirebaseAuth mAuth;
private FirebaseUser mUser;
private String projectId;
private List<DataService> grouplist;
private RecyclerAdapter recyclerAdapter;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAuth = FirebaseAuth.getInstance();
mUser = mAuth.getCurrentUser();
mDatabaseReference = mDatabase.getReference().child("groups");
mDatabase = FirebaseDatabase.getInstance();
mDatabaseReference.keepSynced(true);
grouplist = new ArrayList<>();
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
protected void onStart() {
super.onStart();
grouplist.clear();
mDatabaseReference.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
DataService groupData = dataSnapshot.getValue(DataService.class);
grouplist.add(groupData);
recyclerAdapter = new RecyclerAdapter(Main.this, grouplist);
recyclerView.setAdapter(recyclerAdapter);
recyclerAdapter.notifyDataSetChanged();
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
DataService.java
public class DataService {
public String subject;
public String projectName;
public String endDate;
public String members;
public String userid;
public String creationDate;
public String dropbox;
public String evernote;
public String googleDocs;
public DataService() {
}
public DataService(String subject, String projectName, String endDate, String members, String userid, String creationDate, String dropbox, String evernote, String googleDocs) {
this.subject = subject;
this.projectName = projectName;
this.endDate = endDate;
this.members = members;
this.userid = userid;
this.creationDate = creationDate;
this.dropbox = dropbox;
this.evernote = evernote;
this.googleDocs = googleDocs;
}
public String getCreationDate() {
return creationDate;
}
public void setCreationDate(String creationDate) {
this.creationDate = creationDate;
}
public String getDropbox() {
return dropbox;
}
public void setDropbox(String dropbox) {
this.dropbox = dropbox;
}
public String getEvernote() {
return evernote;
}
public void setEvernote(String evernote) {
this.evernote = evernote;
}
public String getGoogleDocs() {
return googleDocs;
}
public void setGoogleDocs(String googleDocs) {
this.googleDocs = googleDocs;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getProjectName() {
return projectName;
}
public void setProjectName(String projectName) {
this.projectName = projectName;
}
public String getEndDate() {
return endDate;
}
public void setEndDate(String endDate) {
this.endDate = endDate;
}
public String getmembers() {
return members;
}
public void setmembers(String members) {
this.members = members;
}
public String getUserid() {
return userid;
}
public void setUserid(String userid) {
this.userid = userid;
}
}
Using the actual database structure, you cannot get all the groups a user is in, unless you make some changes to your database. In your case, you should consider augmenting your database structure to allow a reverse lookup by creating another node, named groups under each user object, in which you should add all the group ids from which the user is appart of. So your database structure should look like this:
Firebase-root
|
--- users
|
--- userId
|
--- groups
|
--- groupIdOne: true
|
--- groupIdTwo: true
To get all the groups a user is appart, just attach a listener on the groups node and there are all the groups that you need.
But you'll be thinking, why to do this? Why to duplicate data? Well, there is no problem with duplicating data, when it comes to Firebase. This is a quite common practice, which is named denormalization and for that, I recommend you see this video, Denormalization is normal with the Firebase Database.
When you are duplicating data, there is one thing that need to keep in mind. In the same way you are adding data, you need to maintain it. With other words, if you want to update/detele an item, you need to do it in every place that it exists.
I'm new at using maps, how can we get object of custom Class from Map..
i.e.
feedSendModelClass:
public class feedSendModelClass {
private String content;
private String picThumbnail;
private String picurl;
private String videourl;
private String videoThumbnail;
private String mTime;
public feedSendModelClass() {
//blank for firebase
}
public String getTime() {
return mTime;
}
public void setTime(String time) {
mTime = time;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getVideoThumbnail() {
return videoThumbnail;
}
public void setVideoThumbnail(String videoThumbnail) {
this.videoThumbnail = videoThumbnail;
}
public String getVideourl() {
return videourl;
}
public void setVideourl(String videourl) {
this.videourl = videourl;
}
public String getPicurl() {
return picurl;
}
public void setPicurl(String picurl) {
this.picurl = picurl;
}
public String getPicThumbnail() {
return picThumbnail;
}
public void setPicThumbnail(String picThumbnail) {
this.picThumbnail = picThumbnail;
}
}
Map
Map<String, feedSendModelClass> feedKeys = (Map<String,feedSendModelClass>) dataSnapshot.getValue();
Datasnapshot:
DataSnapshot { key = feedsMetaPool, value = {20160708155218759={content=bzzzhss, picurl=https://firebasestorage.googleapis.com/v0/b/rootssahaj.appspot.com/o/feedsImages%2FnonThumbs%2F201607081552353353553518759sahaj9917730102?alt=media&token=ce1c6e7c-28c5-442e-9405-4468bf5fc204, time=08 Jul, picThumbnail=https://firebasestorage.googleapis.com/v0/b/rootssahaj.appspot.com/o/feedsImages%2Fthumbs%2F20353353535355353160708155218759sahaj9917730102?alt=media&token=14d33963-f3da-4407-a08f-ab0afce21ace}, 20160708164100152={content=sj sjs skss sksssvsjm, picurl=https://firebasestorage.googleapis.com/v0/b/rootssahaj.appspot.com/o/feedsImages%2FnonThumbs%2F201607081641003535152sahaj9917730102?alt=media&token=323c4a27-1850-4bc9-adea-34e5319ac506, time=08 Jul, picThumbnail=https://firebasestorage.googleapis.com/v0/b/rootssahaj.appspot.com/o/feedsImages%2Fthumbs%2F20160708164100152sahaj9917730102?alt=media&token=0b064b46-2f14-49af-b3e6-7a573f6c2d3f}, 20160708142314069={content=dadax, picurl=https://firebasestorage.googleapis.com/v0/b/rootssahaj.appspot.com/o/feedsImages%2FnonThumbs%2F2016070rdgdg54353535358142314069sahaj9917730102?alt=media&token=19d03f11-d12f-43c1-96f5-ca397a9179c9, time=08 Jul, picThumbnail=https://firebasestorage.googleapis.com/v0/b/rootssahaj.appspot.com/o/feedsImages%2Fthumbs%2F20160735353508142314069sahaj9917730102?alt=media&token=ab9c73eb-ec44-46ae-9daa-6fc508cb08a6} }
This has become tricky for me..Thanks..
There could be some other way round to do it through firebase
If you are asking how you retrieve the feedSendModelClass object from the map named feedKeys, then this syntax should work:
feedKeys.get(key)
The key is your String, and the object is the feedSendModelClass object. However, first you'd need to put key and value pairs into the map (so it's not empty), with feedKeys.put(key, value), where the key is a String and value is the feedSendModelClass.
If this totally doesn't answer your question, I apologize, but from your description, it is a bit difficult to understand what you need help with.
On an unrelated note, it would be more appropriate to name your class FeedSendModelClass, as per Java conventions classes start with a capital letter.
If you're using Firebase then you can use a ChildEventListener. It calls the onChildAdded() method once for every initial child in the node and everytime a new child is added. Then you can add the Object to an ArrayList directly (or do whatever you want with it)
ArrayList<feedSendModelClass> feedKeysArrayList = new ArrayList<>();
DatabaseReference feedKeysRef = FirebaseDatabase.getInstance().getReference("path/to/the/feedkeys");
feedKeysRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
feedKeysArrayList.add(dataSnapshot.getValue(feedSendModelClass.class));
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
// Add appropriate code
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
// Add appropriate code
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
// Add appropriate code
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Add appropriate code
}
});