Hello I am new to Firebase database. Currently I am developing a android application. I am looking for a help, Below is my Firabase Data Structure. Can anyonce please tell me how to retrive the data.
Requirement is I have to retrieve the all the companies. Upon selecting the a specific company, it has to fetch the corresponding company coordinates into polygon shape variable.
Please Help
Why not have a structure like:
companyName/info
Instead of
Firebase ID/Companyname/info
i.e use update or set instead of push
public class CompanyIds{
public List<Company> companies;
}
FirebaseDatabase.getInstance()
.getReference("parent node path of these ID's");
Now in FirebaseRecyclerAdapter what you can do is:-
#Override
protected void populateViewHolder(final MessagesHolder viewHolder, CompanyIds model, int position) {
Company = model.companies.get(0);
//Set data on your view from Company model
}
As your ID is having only one company then you get that only company from the first index.
Now after clicking on any item, you can easily get the details for a company like coordinates or anything else in the same way you set the data in the adapter. It won't be a problem.
public class Company{
List<String> Cordinates;
List<Employees> Employees;
//Define other fields
}
Basically I got the answer from repetitive hits and tries while working on the similar problem.
Look when you go for general approach of add addValueEventListner(), you get a snapshot of the database with respect to your root node. Thus on the first addValueListner() callback, get the reference of your child node and then addChildEventListner() on it. So here is what i suggest:
DatabaseReference databaseReference=FirebaseDatabase.getInstance().getReference();
databaseReference.addValueEventListner(new ValueEventListner(){
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot){
//here your snapshot is considered with respect to root. So you get the reference of child node now
datasnapshot.child("Bureau 507").getRef().addChildEventListner(new
ChildEventListner){
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s){
for(DataSnapshot data: dataSnapshot.getChildren()){
//Now you are at the subtree of Bureua 507. So now you get your data in the form of
key and values
}
//remaining callbacks
Related
I am designing a simple basic chat app using firebase real time database and i've designed everything well, however, i'm facing one sllight issue. My chats keep duplicating themselves on the inbox page (the page whrere the chats are laid out for a user to select which chat he wants to open and start talking).
I've attached an image of what i mean below.
Screenshot of the phone screen
The code i am using to get the chats and display them in the recycler view is given below. I have a directory called Conversations in my DB that saves a user's Id and under it, theres a child of each and every person he chats wit, under which is the last message and a seen boolean.
Database Structure
The code is given below
convoref = FirebaseDatabase.getInstance().getReference().child("Conversations").child(currentUid);
and then..
public void getConvoIds() {
convoref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
for(DataSnapshot convo : dataSnapshot.getChildren()){
boolean isMessageSeen = false;
String lastMessage = "";
if(convo.child("seen").getValue() != null) {
isMessageSeen = (boolean) convo.child("seen").getValue();
}else{
Log.i("nolastseen", "location is null");
}
if(convo.child("lastMessage").getValue() != null) {
lastMessage = convo.child("lastMessage").getValue().toString();
}else{
Log.i("nolastMessage", "location is null");
}
Log.i ("the_convo_partner_key", convo.getKey());
Log.i ("lastseenmessage", lastMessage);
Log.i ("seenstate", String.valueOf(isMessageSeen));
FetchConvoInfo(convo.getKey(), isMessageSeen, lastMessage );
}
}
}
the fetch convo information functuion is below
public void FetchConvoInfo(final String key, final boolean isMessageSeen, final String lastMessage){
FirebaseDatabase.getInstance().getReference().child("Users").child(key).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
boolean chatExists = false;
String username = "";
String thumbnail = "";
String chatPartner;
chatPartner = key;
if(dataSnapshot.child("username").exists()){
username = dataSnapshot.child("username").getValue().toString();
}
if(dataSnapshot.child("thumbnail").exists()){
thumbnail = dataSnapshot.child("thumbnail").getValue().toString();
}
ConvoClass obj= new ConvoClass(chatPartner, username, thumbnail, isMessageSeen, lastMessage);
resultConvos.add(obj);
mConvoAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
Any help would be greatly appreciated. i cant seem to figure out why the chat duplicates.
In your onDataChanged method, you are going through every child of the dataSnapshot. Each child of the data snapshot indicates a particular conversation of that particular currentUid guy. So when you are going through every child of the dataSnapshot you are adding all its children to the listview or recyclerview(I don't know what you are using. But you are adding it to the adapter). So you are adding the old data again and again whenever some new data must be added. Hence-duplicate data.
There are two common solutions.
The first is naive method. Do what you are doing right now. But while adding an item (chat, you will call it in your case, I think) to the adapter, check if it is already present in the container resultConvos. That will prevent you from adding duplicate chats. I am sure it is obvious to you also why this method is inefficient. You are unnecessarily having to go through every conversation of a person. It takes O(n) time for just adding one item.
The second method is the recommended method. Remove all the code of ValueEventListener. Instead use ChildEventListener. I don't know if you are aware of it. Check this.
ChildEventListener has mainly 4 methods instead of onDataChanged. Among that, what you require here is onChildAdded. Just like your onDataChanged, it has one argument- a data snapshot. But this data snapshot contains only the newly added child, whereas the data snapshot in onDataChanged contains the whole data of the conversations of that particular user (that means the whole list). So using the data snapshot provided by onChildAdded you can directly add only that chat to the adapter, which takes O(1) time.
For more about ChildEventListener, read that link I attached
i am trying to get reference or snapshot of newly added child on firebase
i have solve it by different way
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
}
myRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s)
{
}
My question is that both are return a complete snapshot means all this nodes in firebase is there any way getting child which newly added ("this will improve speed")
When you attach a listener to a location or a query, the listener will initially fire with all data that exists at that location or that matches the query. The database has no concept of "new" data, although your application may have that concept.
There are a few options to reduce the data that is retrieved, or the data that is passed to your listener:
If you're using disk persistence, the application may have a previous snapshot of the data in its disk cache. In that case, only the delta between the previous snapshot and the current snapshot is retrieved from the server. But the entire current snapshot is passed to your listener, so that you can render the UI correctly for the while current data.
If you only want to process the data since a certain moment, you'll need to only request that data from the database. You can typically do this by storing the key of the data you last processed in your local state, and then using a query like this to only get the new update:
myRef.orderByKey().startAt("mostRecentKeyWeHaveAlreadyProcessed").add...Listener
I am currently developing an app with Android Studio.
Now I would like to use the Fire DB, in order to take over the information from the data base in an Arraylist when starting the app. In this case, a node in the database should be saved as an object with its attributes.
The structure of the DB is still flexible. I had the plan to make a numbering of 1 and below the indexes all the attributes of one objet.
If anything else makes sense, this can still be changed
How can I read these and store them in a object per index, which is then put into a Array list?
I had already found several online examples, but none got to work.
Therefore, I would be grateful for an input that I can test and then possibly discuss it.
Please add some sample code to understand us what you do.
You need to do following things,
1) Model Class which contains setter and getter methods (same name as you store in firebase)
If you multiple node inside one object then,
2) RecyclerView and RecyclerAdapter Class
3) DatabaseRefrence to access your data.
example code to retrive data from firebase
final List<Certificates> list=new ArrayList<>();
DatabaseReference reference= FirebaseDatabase.getInstance().getReference().child("Object");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot)
{
list.clear();
for (DataSnapshot snapshot:dataSnapshot.getChildren())
{
Model model=snapshot.getValue(Model.class);
list.add(model);
}
RecyclerAdapter adapter=new RecyclerAdapter(list,Activity.this);
recyclerView.setLayoutManager(new LinearLayoutManager(CertificatesActivity.this));
recyclerView.setAdapter(adapter);
recyclerView.addItemDecoration(new DividerItemDecoration(recyclerView.getContext(),DividerItemDecoration.VERTICAL));
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError)
{
//handle error here
}
});
If you need help to understand tell me.
I have several strings stored under specific reference: mReference.child(rID).child(userID2) which I want to retrieve using childEventListener as I am doing some task also when these string gets removed and that is only possible with onChildRemoved of ChildEventListener.
Here's what I have tried:
mReference.child(rID).child(userID2).addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Log.d("dataHEre", dataSnapshot.getValue().toString());
}
}
The problem is that I'm unable to retrieve data using keys here as dataHEre is logging out:
D/dataHEre: 28.8419556
D/dataHEre: 78.779063
D/dataHEre: 3
D/dataHEre: Railway Colony
D/dataHEre: Sleep
D/dataHEre: 12:36 AM
D/dataHEre: Superman
which are values?
So, I want to know how can I retrieve data here using keys and using ChildEventListener and then assign the data retrieved to various strings?
I think that you are doing your query in the wrong way. onChildAdded method is retrieving you each child of a specific value (userID2 I suppose). If that is what you want, then just use a onValueEventListener() to retrieve the whole dataSnapshot of your userId2 node each time that it changes.
If you want to retrieve the data just once, you should use onSingleValueEventListener(). And OnChildEvent() is used to retrieve lists of data where you want to track each of the child individually. For example if you attach an OnChildEventListener to mReference.child(rID) you will get a OnChildAdded for each userId, what is pretty usefull like for example fill a RecyclerView or a ListView being able to update each item individually together with your Firebase Data.
If i'm not wrong what you want is just get updates of your userId2 reference, in that case attach a OnValueEventListener to that reference and you will get a call each time a value is modified, deleted, or added.
firebaseDatabaseRef.addValueEventListener(new ValueEventListener() {
#Override public void onDataChange(DataSnapshot dataSnapshot) {
customPOJO customPOJO = dataSnapshot.getValue(YourCustomPOJO.class);
customPOJO.getName();
customPOJO.getEmail();
customPOJO.getfavoriteFood();
//and so on....
}
#Override public void onCancelled(DatabaseError databaseError) {
}
});
I have the following data structure on firebase for the user MF0qeRA4p7djfjgXxqwFOck3m6p02. I want to get the value of item3 to populate a single field into the User interface on an Android App. I have been looking through samples on Stackoverflow, but all I have found are outdated and do not work with the current version of firebase. I'm new to firebase completely and this is my first app on android. I've got the oncreate user method to populate the users email address and add the 4 item fields, but retrieving the data I'm completely lost and I am not sure where to even begin.
-Users
---MF0qeRA4p7djfjgXxqwFOck3m6p02
------item1:"1"
------item2:"2"
------item3:"3"
------item4:"4"
According to what I can identify is, you are facing problem retrieving data from this reference. Here is the code:
final DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("Users");
databaseReference.child("MF0qeRA4p7djfjgXxqwFOck3m6p02").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Map<String, Object> map=(Map<String, Object>)dataSnapshot.getValue();
String item3=(String)map.get("item3");
display(item3);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Hope this helps.
You can create a custom model and inside you can insert elements. Something like this:
public class Item {
private List<Object> ojects;
}
There you can save instance of Item on database. In this case you have more controll. Other case is to use push() method, that will generate a new encoded key, something like this:
mDatabase.child("items").push().put(new Object());