Graphview : Display Arraylist as X axis label - android

I am using GraphView to plot a data from firebase database.
What i want to achieve is display tmpHr as y value, with Timestamp as the label in x axis. I have retrieved the data from firebase, and I have successfully plotted the tmpHr in y axis. I have tried the method below, but it doesn't work. How can I get this the right way?
Any help would be appreciated. Thank you very much.
public class RetrieveApp extends AppCompatActivity {
FirebaseAuth auth;
FirebaseUser user;
int hrValue;
String hrValueTimestamp;
ArrayList<Integer> array2; //array for tmpHr value
ArrayList<String> array7; //array for hrValueTimestamp
LineGraphSeries<DataPoint> series ;
int x=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_retrieve_app);
DatabaseReference userdatabase = FirebaseDatabase.getInstance().getReference().child("Users");
auth = FirebaseAuth.getInstance();
user = auth.getCurrentUser();
final GraphView graph = (GraphView)findViewById(R.id.graph);
series = new LineGraphSeries<>();
graph.addSeries(series);
DatabaseReference ref = userdatabase.child(user.getUid());
array2 = new ArrayList<>(); //array for tmpHR
array7 = new ArrayList<>(); //array for hrValueTimestamp
ref.child("hrvalue").child("nilaihr").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
hrValue = dataSnapshot.child("tmpHR").getValue(Integer.class);
hrValueTimestamp = dataSnapshot.child("Timestamp").getValue(String.class);
Log.i("timestamp value", "timestamp value " + hrValueTimestamp);
Log.i("hr value", "hr value " + hrValue);
array2.add(hrValue);
array7.add(hrValueTimestamp);
x = x+1;
DataPoint point = new DataPoint(x, hrValue);
series.appendData(point, false, 1000);
graph.setCustomLabelFormatter(new CustomLabelFormatter() {
#Override
public String formatLabel(double value, boolean isValueX) {
if (isValueX) {
return (hrValueTimestamp);
}
return null;
}
});
}
#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) {
}
});
}
}

You can do it using static labels formatter:
StaticLabelsFormatter staticLabelsFormatter = new StaticLabelsFormatter(graph);
staticLabelsFormatter.setHorizontalLabels(array7); // <- array with you labels
graph.getGridLabelRenderer().setLabelFormatter(staticLabelsFormatter);
Since the labels are very long, maybe you'll want to set an angle for them so that they do not overlap:
graph.getGridLabelRenderer().setHorizontalLabelsAngle(135);

Related

Retrieving data under the same child name but different date

I am using firebase database to retrieve user data into my android studio application. I am looking to sum all of the numbers under the child ("BlueCount") together to get an all time total. I am having trouble retrieving all the "BlueCount" data from each different date.
I am trying to add all the underlined "BlueCount" values together.
I have tried this but i can only retrieve data from the current date...
private TextView blueValue;
private TextView redValue;
private TextView greenValue;
private TextView yellowValue;
private ArrayList<Integer> blist = new ArrayList<>();
private ArrayList<Integer> rlist = new ArrayList<>();
private ArrayList<Integer> glist = new ArrayList<>();
private ArrayList<Integer> ylist = new ArrayList<>();
private ArrayList<Integer> bblist = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dataview);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
blueValue = (TextView)findViewById(R.id.blueValue);
redValue = (TextView)findViewById(R.id.redValue);
greenValue = (TextView)findViewById(R.id.greenValue);
yellowValue = (TextView)findViewById(R.id.yellowValue);
final FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user == null){
return;
}
final DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
final Date date = new Date();
String userID = user.getUid();
String strDate = dateFormat.format(date);
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference databaseReference = database.getReference();
databaseReference.child("users")
.child(userID)
.child(strDate)
.child("BlueCount").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
int num = 0;
String holder = String.valueOf(dataSnapshot.getValue());
num += Integer.parseInt(holder.trim());
blist.add(num);
int sum = 0;
for (int counter=0;counter<blist.size();counter++){
sum+= blist.get(counter);
}
blueValue.setText(" "+sum);
}
#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) {
}
});
Firebase can only load complete nodes, or nodes that can be queries. So you'll have to load all data, and then loop over each level to determine the totals.
Something like this should do the trick:
DatabaseReference databaseReference = database.getReference();
DatabaseReference userReference = databaseReference.child("users").child(userID);
userReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
long totalBlueCount = 0;
for (DataSnapshot yearSnapshot: dataSnapshot.getChildren()) {
for (DataSnapshot monthSnapshot: yearSnapshot.getChildren()) {
for (DataSnapshot daySnapshot: monthSnapshot.getChildren()) {
DataSnapshot blueSnapshot = daySnapshot.child("BlueCount");
long dayBlueCount = 0;
for (DataSnapshot daySnapshot: monthSnapshot.getChildren()) {
long count = Long.parseLong(daySnapshot.getValue(String.class));
dayBlueCount += count;
}
System.out.println(yearSnapshot.getKey()+"-"+monthSnapshot.getKey()+"-"+daySnapshot.getKey()+": blue count = "+dayBlueCount);
totalBlueCount += dayBlueCount;
}
}
}
System.out.println("Total blue count = "+totalBlueCount);
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
}
I would consider if the hierarchy really helps you here, as the code would be a lot simpler if each day was just at the same level under a user "2019-07-16", "2019-07-17", etc.

Populating Recycler View From Nested Queries in Firebase

I am trying to populate a recycler view using nested queries. The first query goes to groups_list node and takes data in the node and the unique key. Then it goes to groups node with the key and gets data under that key. The result of both the queries needs to be updated in recycler view.
In short, the first query gets some data and a key, the key is used to make the second query. The result from both these queries need to be updated in the recycler view. I am using a model class and recycler view adapter for this.
But I am getting an error below.
My Fragment is as follows:
// Firebase
fbDatabaseRootNode = FirebaseDatabase.getInstance().getReference();
fbDatabaseRefGroupList = fbDatabaseRootNode.child("groups_list").child(current_user_id);
fbDatabaseRefGroups = fbDatabaseRootNode.child("groups");
fbDatabaseRefGroupList.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
// Array to Get Group List
lGroupsList = new ArrayList<>();
if (dataSnapshot.exists()) {
// Clear Array to Get Group List
lGroupsList.clear();
for (DataSnapshot glSnapshot : dataSnapshot.getChildren()) {
// Use The Model To Format Array List and Pass It Into It
GroupsListModel g = glSnapshot.getValue(GroupsListModel.class);
// Array to Get Group List
lGroupsList.add(g);
String groupID = String.valueOf(glSnapshot.getKey());
fbDatabaseRefGroups.child(groupID).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
for (DataSnapshot gSnapshot : dataSnapshot.getChildren()) {
// Use The Model To Format Array List and Pass It Into It
GroupsListModel g = gSnapshot.getValue(GroupsListModel.class);
// Array to Get Group List
lGroupsList.add(g);
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
aGroupList = new GroupsListAdapter(getContext(), lGroupsList);
rvGroupList.setAdapter(aGroupList);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
System.out.println("The read failed: " + databaseError.getCode());
}
});
And My Firebase Database Structure Looks Like
"groups" : {
"-LaPfENd0G4pHlejrcd6" : {
"group_creation_date" : 1553078221782,
"group_logo" : "0",
"group_member_count" : "0",
"group_name" : "dog lovers",
"group_tagline" : "we love dogs..."
},
"-LaPhG0YHnF3FG0Czxom" : {
"group_creation_date" : 1553078751686,
"group_logo" : "0",
"group_member_count" : "0",
"group_name" : "hi",
"group_tagline" : "hello"
}
},
"groups_list" : {
"F81wvGx9a7fXRrfVPQMhQtkM0wv2" : {
"-LaPfENd0G4pHlejrcd6" : {
"block_status" : "0",
"hide_status" : "0",
"notification_status" : "0",
"pin_sequence" : "0",
"report_status" : "0"
},
"-LaPhG0YHnF3FG0Czxom" : {
"block_status" : "0",
"hide_status" : "0",
"notification_status" : "0",
"pin_sequence" : "0",
"report_status" : "0"
}
}
},
The Model Class Is
public class GroupsListModel {
private String block_status;
private String hide_status;
private String notification_status;
private String pin_sequence;
private String report_status;
private String group_name;
private Long group_creation_date;
private String group_logo;
private String group_member_count;
private String group_tagline;
public GroupsListModel() {
}
public GroupsListModel(String block_status, String hide_status, String notification_status, String pin_sequence, String report_status, String group_name, Long group_creation_date, String group_logo, String group_member_count, String group_tagline) {
this.block_status = block_status;
this.hide_status = hide_status;
this.notification_status = notification_status;
this.pin_sequence = pin_sequence;
this.report_status = report_status;
this.group_name = group_name;
this.group_creation_date = group_creation_date;
this.group_logo = group_logo;
this.group_member_count = group_member_count;
this.group_tagline = group_tagline;
}
public String getBlock_status() {
return block_status;
}
public void setBlock_status(String block_status) {
this.block_status = block_status;
}
public String getHide_status() {
return hide_status;
}
public void setHide_status(String hide_status) {
this.hide_status = hide_status;
}
public String getNotification_status() {
return notification_status;
}
public void setNotification_status(String notification_status) {
this.notification_status = notification_status;
}
public String getPin_sequence() {
return pin_sequence;
}
public void setPin_sequence(String pin_sequence) {
this.pin_sequence = pin_sequence;
}
public String getReport_status() {
return report_status;
}
public void setReport_status(String report_status) {
this.report_status = report_status;
}
public String getGroup_name() {
return group_name;
}
public void setGroup_name(String group_name) {
this.group_name = group_name;
}
public Long getGroup_creation_date() {
return group_creation_date;
}
public void setGroup_creation_date(Long group_creation_date) {
this.group_creation_date = group_creation_date;
}
public String getGroup_logo() {
return group_logo;
}
public void setGroup_logo(String group_logo) {
this.group_logo = group_logo;
}
public String getGroup_member_count() {
return group_member_count;
}
public void setGroup_member_count(String group_member_count) {
this.group_member_count = group_member_count;
}
public String getGroup_tagline() {
return group_tagline;
}
public void setGroup_tagline(String group_tagline) {
this.group_tagline = group_tagline;
}
}
And The Error is
Can't convert object of type java.lang.Long to type com.example.myproject
The logs from datasnapshots are coming as follows... first one...
The log from second one...
Possible Solution 1 (Passing To Recycler View An Issue Otherwise Working)
This seems to be getting the data in proper sequence now just have to pass it into the Model Array List and Set The Adapter
// Get The Data
fbDatabaseRefGroupList.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
if (dataSnapshot.exists()) {
final String groupID = dataSnapshot.getKey();
final String blockStatus = (String) dataSnapshot.child("block_status").getValue();
final String hideStatus = (String) dataSnapshot.child("hide_status").getValue();
final String notificationStatus = (String) dataSnapshot.child("notification_status").getValue();
final String pinSequence = (String) dataSnapshot.child("pin_sequence").getValue();
final String reportStatus = (String) dataSnapshot.child("report_status").getValue();
fbDatabaseRefGroups.child(groupID).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String groupName = (String) dataSnapshot.child("group_name").getValue();
String groupTagLine = (String) dataSnapshot.child("group_name").getValue();
String groupMemberCount = (String) dataSnapshot.child("group_name").getValue();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
#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) {
}
});
Possible Solution 2 (List Merging Is An Issue - Otherwise Working)
// Firebase
fbDatabaseRootNode = FirebaseDatabase.getInstance().getReference();
fbDatabaseRefGroupList = fbDatabaseRootNode.child("groups_list").child(current_user_id);
fbDatabaseRefGroups = fbDatabaseRootNode.child("groups");
// Array to Get Group List
lGroupsListList = new ArrayList<>();
lGroupsList = new ArrayList<>();
lCombinedList = new ArrayList<>();
// Clear Array to Get Group List
lGroupsList.clear();
// Clear Array to Get Group List
lGroupsListList.clear();
// Clear Array to Get Group List
lCombinedList.clear();
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
// Use The Model To Format Array List and Pass It Into It
GroupsListModel g = ds.getValue(GroupsListModel.class);
// Array to Get Group List
lGroupsListList.add(g);
final String key = ds.getKey();
final String blockStatus = (String) ds.child("block_status").getValue();
DatabaseReference keyRef = fbDatabaseRootNode.child("groups").child(key);
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Use The Model To Format Array List and Pass It Into It
GroupsListModel g = dataSnapshot.getValue(GroupsListModel.class);
// Array to Get Group List
lGroupsList.add(g);
String groupName = (String) dataSnapshot.child("group_name").getValue();
Log.d(TAG, "groupdetails: " + key + "--" + groupName + "--" + blockStatus);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
keyRef.addListenerForSingleValueEvent(eventListener);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
aGroupList = new GroupsListAdapter(getContext(), lGroupsList);
rvGroupList.setAdapter(aGroupList);
fbDatabaseRefGroupList.addListenerForSingleValueEvent(valueEventListener);
#Prateek Jain Your answer is giving error please see screenshot below:
Working Solution Based on Prateek Jains Inputs
public class GroupsListFragment extends Fragment {
private static final String TAG = "GroupsListFragment";
// Recycler View
private RecyclerView rvGroupList;
private GroupsListAdapter aGroupList;
private List<GroupsListModel> lGroupsListList;
private List<GroupsListModel> lGroupsList;
private List<GroupsListModel> lCombinedList;
// Firebase
private FirebaseAuth mAuth;
private DatabaseReference fbDatabaseRootNode;
private DatabaseReference fbDatabaseRefGroupList;
private DatabaseReference fbDatabaseRefGroups;
private String current_user_id;
private String groupID;
private List<String> lgroupIDs;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_groups_list, container, false);
mAuth = FirebaseAuth.getInstance();
current_user_id = mAuth.getCurrentUser().getUid();
// Init Recycler View
rvGroupList = view.findViewById(R.id.f_groups_list_groups_list);
rvGroupList.setHasFixedSize(true);
rvGroupList.setLayoutManager(new LinearLayoutManager(getActivity()));
// Firebase
fbDatabaseRootNode = FirebaseDatabase.getInstance().getReference();
fbDatabaseRefGroupList = fbDatabaseRootNode.child("groups_list").child(current_user_id);
fbDatabaseRefGroups = fbDatabaseRootNode.child("groups");
// Get The Data
fbDatabaseRefGroupList.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
// Array to Get Group List
lGroupsList = new ArrayList<>();
if (dataSnapshot.exists()) {
// Clear Array to Get Group List
lGroupsList.clear();
final String groupID = dataSnapshot.getKey();
final String blockStatus = (String) dataSnapshot.child("block_status").getValue();
final String hideStatus = (String) dataSnapshot.child("hide_status").getValue();
final String notificationStatus = (String) dataSnapshot.child("notification_status").getValue();
final String pinSequence = (String) dataSnapshot.child("pin_sequence").getValue();
final String reportStatus = (String) dataSnapshot.child("report_status").getValue();
fbDatabaseRefGroups.child(groupID).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
Long groupCreationDate = (Long) dataSnapshot.child("group_creation_date").getValue();
String groupLogo = (String) dataSnapshot.child("group_logo").getValue();
String groupMemberCount = (String) dataSnapshot.child("group_member_count").getValue();
String groupName = (String) dataSnapshot.child("group_name").getValue();
String groupTagLine = (String) dataSnapshot.child("group_tagline").getValue();
lGroupsList.add(new GroupsListModel(blockStatus, hideStatus, notificationStatus, pinSequence,
reportStatus, groupName, groupCreationDate, groupLogo, groupMemberCount, groupTagLine));
aGroupList.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
aGroupList = new GroupsListAdapter(getContext(), lGroupsList);
rvGroupList.setAdapter(aGroupList);
}
}
#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) {
}
});
return view;
}
}
You have to add the required data to the list which is being used by your adapter to render the views. Once that is done you must call notifyDataSetChanged, so that adapter can reload its data from the updated list.
fbDatabaseRefGroups.child(groupID).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String groupName = (String) dataSnapshot.child("group_name").getValue();
String groupTagLine = (String) dataSnapshot.child("group_name").getValue();
String groupMemberCount = (String) dataSnapshot.child("group_name").getValue();
lGroupsList.add(new GroupsListModel(groupName, groupMemberCount, groupTagLine));
aGroupList.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});

What is going wrong with the code to display messages from firebase?

I am trying to display the messages received in the firebase database to the desired user.
The text, user1 sends is displayed properly on his device, but not in user2 device even though, the message reaches the firebase database. This is the main problem.
I am using the following code to check for new messages:
private void checkMessage(){
final DatabaseReference rRef = FirebaseDatabase.getInstance().getReference();
final DatabaseReference uRef = rRef.child("users");
final DatabaseReference mRef = uRef.child(toUid);
final DatabaseReference kRef = mRef.child("rec_msg");
kRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
if(mAuth.getCurrentUser().getUid().equals(toUid)) {
Map map = (Map) dataSnapshot.getValue();
assert map != null;
String message = map.get("rec_msg").toString();
addMessageBox(message, 2);
}
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
if(mAuth.getCurrentUser().getUid().equals(toUid)) {
Map map = (Map) dataSnapshot.getValue();
assert map != null;
String message = map.get("rec_msg").toString();
addMessageBox(message, 2);
}
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.i("Error", databaseError.getDetails());
}
});
The code that prints the box and shows the text on the screen is like:
private void addMessageBox(String message, int type){
TextView tv = new TextView(Main5Activity.this);
tv.setText(message);
tv.setPadding(20, 30, 30, 20);
tv.setTextSize(1, (float) 20.1);
LinearLayout.LayoutParams lp2 = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
lp2.weight = 1.0f;
if (type == 1) {
lp2.gravity = Gravity.END;
tv.setBackgroundResource(R.drawable.rounded_rectangle_grey);
} else {
lp2.gravity = Gravity.START;
tv.setBackgroundResource(R.drawable.rounded_rectangle_violet);
}
tv.setLayoutParams(lp2);
layout.addView(tv);
scrollView.fullScroll(ScrollView.FOCUS_DOWN);
}
The send button code works as following:
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String meText = message.getText().toString();
if (!meText.equals("")) {
addMessageBox(meText, 1);
storeToUID(toUid, fromUid);
sendMessage(message.getText().toString(), toUid);
checkMessage();
}
message.setText("");
}
});
The database looks something like this:
The 'sendMessage()' and 'storeToUID()' just store the values on the firebase database.
Also, the 'checkMessage()' when not added inside the send button's listener code, crashes the app.
Where and how should I place the checkMessage() code so that the app works as it should?

Minimize Downloads from Firebase

In my NotificationListener of my application I am listening (and syncronizing with my SQLite) to new or changed data from Firebase.
In the first case I would like to check if the status of a loaned book has changed. Therefor I use the following code in onStartCommand:
databaseLoanedBooks.orderByChild("contactId").equalTo(firebase_uid).addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
String book_id = dataSnapshot.child("bookId").getValue(String.class);
String book_status = dataSnapshot.child("bookStatus").getValue(String.class);
DatabaseHelper db = new DatabaseHelper(getApplicationContext());
List<String> all_book_ids = db.getAllBookIds();
if (all_book_ids.contains(book_id)){
// some action... check for status, if status=x output of notification
}
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Moreover I would like to check if there is a new message about the loaned book at the server. Therefor I use the following code in onStartCommand of my NotifiactionListener:
final List<String> all_book_ids = db.getAllBookIds();
// iterate through all book-ids the user has loaned at the moment (and saved in SQL)
for (int i = 0; i < all_book_ids .size(); i++) {
final String check_book_id = all_book_ids.get(i);
databaseMessage.child(check_book_id).addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
ChatMessage chatMessage = dataSnapshot.getValue(ChatMessage.class);
String message_id = dataSnapshot.child("messageId").getValue(String.class);
String message_book_id = dataSnapshot.child("messageBookId").getValue(String.class);
String message_uid = dataSnapshot.child("messageUid").getValue(String.class);
String message_text = dataSnapshot.child("messageText").getValue(String.class);
String message_time = String.valueOf(chatMessage.getMessageTime());
DatabaseHelper db = new DatabaseHelper(getApplicationContext());
final List<String> all_message_ids = db.getAllMessagesIds();
final List<String> all_book_ids = db.getAllBookIds();
String new_message = getString(R.string.text_new_message);
if (all_book_ids.contains(message_book_id)) {
if (all_message_ids.contains(message_id_changed)) {
// already exists
} else {
ContentValues values_new = new ContentValues();
values_new.put(DatabaseHelper.COLUMN_CHAT_FCM_ID, message_id); values_new.put(DatabaseHelper.COLUMN_CHAT_BOOK_ID, message_book_id);
values_new.put(DatabaseHelper.COLUMN_CHAT_TEXT, message_text_changed); values_new.put(DatabaseHelper.COLUMN_CHAT_BOOK_ID, message_uid);
values_new.put(DatabaseHelper.COLUMN_CHAT_TIME, message_time);
todoUri = getContentResolver().insert(DataContentProvider.CONTENT_URI_CHATS, values_new);
HashMap<String, String> user_session = session.getUserDetails();
// UID from sharedpreferences
String noti_status = user_session.get(SessionManager.KEY_NOTIFICATION);
String user_name_chat_sql = String.valueOf(db.getContactName(message_uid));
String book_name = String.valueOf(db.getBookNameForWA(message_book_id));
user_name_chat_sql = user_name_chat_sql.replaceAll("\\p{P}", "");
book_name = book_name.replaceAll("\\p{P}", "");
showNotificationNewMessage(new_message, user_name_chat_sql, message_text, book_name);
}
}
}
#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) {
}
});
}
With this code I have a data usage of approximately 2 MB per day per user. So my question is: How can I minimize my downloads and following from this my data usage? In the code to check for new messages I tried to use a for-loop to restrict the gathered data only for the books of the respective user, but this is unfortunately not the solution. How can I solve this problem?

Retrieve a List of Objects from another object stored in Firebase Database

I've searched a lot of posts in order to find a solution, but i couldn't find one.
I have 2 classes a Recipe class:
public class Recepta {
private String nom;
private List<Ingredient> ingredients;
private List<String> pasos;
public Recepta() {
}
public Recepta(String nom,List<Ingredient> ingredients, List<String> pasos) {
this.nom = nom;
this.ingredients = ingredients;
this.pasos = pasos;
}
//Getter and setters
}
and my Ingredient class:
public class Ingredient {
private String nom;
private String quantitat;
public Ingredient(){
}
public Ingredient(String nom,String quantitat){
this.nom = nom;
this.quantitat = quantitat;
}
//Getter and setters
}
And my DB's structure :
3ER2U0QSDTMHRdKA0eO231UCQeY2
8eJaHRU9f5ZrVogqhx0Hj1iFcgG2
-jdhd
-ingredients
-0
-nom: "bdhd"
-quantitat: "b,bzh"
-nom:"jdhd"
-pasos
-0: "djdjjd"
-jdjd
-jdjdvshs
AfcGeBzvdLRq19J3kRk3CVg30np2
fk39ClAVaQNFQCONU9Agp0KfUUf1addclose
As you can see, "pasos" is a List of String and "ingredients" is a List of Ingredient.
What I can't find out is how can I retrieve those lists from database as I want to get a List of Recepta.
I've tried a lot of things but all were wrong as it didn't retrieve any of the lists.
That's what I've tried, but i know that doesn't work because Firebase DB doesn't store lists as a List
final FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
final DatabaseReference listReference = FirebaseDatabase.getInstance().getReference(user.getUid());
listReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(final DataSnapshot listSnapshot: dataSnapshot.getChildren()){
receptas.add(listSnapshot.getValue(Recepta.class));
}
listReceptaAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
I also know that FB DB work with HashMaps but i dont know how to retrieve them or pass from a hashmap to a list without having to go through every position of hashmap
So what should I do? Thank you in advance
I think the below example would help to integrate two data in one list in firebase database
public static ArrayList<MuteModel> muteModelList;
public void updateMuteListServer(){
DatabaseReference frndMuteRef = FirebaseDatabase.getInstance().getReference().child("users/" + getFirebaseUser().getUid().trim() + "/friendlists");
Query queryRef = frndMuteRef.orderByChild(MUTE).equalTo(YES);
queryRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
GenericTypeIndicator<HashMap<String,MuteModel>> t= new GenericTypeIndicator<HashMap<String,MuteModel>>() { };
HashMap<String,MuteModel> hashMap= (HashMap<String,MuteModel>)dataSnapshot.getValue(t);
if(hashMap!=null) {
muteModelList = new ArrayList<MuteModel>(hashMap.values());
for (MuteModel muteModel: muteModelList){
muteModel.setIsgroup(NO);
}
}else{
muteModelList = new ArrayList<MuteModel>();
}
findGroupMuteList();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void findGroupMuteList() {
DatabaseReference groupMuteRef = FirebaseDatabase.getInstance().getReference().child("users/" + getFirebaseUser().getUid().trim() + "/"+GROUPS);
Query queryRef = groupMuteRef.orderByChild(MUTE).equalTo(YES);
queryRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
GenericTypeIndicator<HashMap<String,MuteModel>> t= new GenericTypeIndicator<HashMap<String,MuteModel>>() { };
HashMap<String,MuteModel> hashMap= (HashMap<String,MuteModel>)dataSnapshot.getValue(t);
ArrayList<MuteModel> properties;
if(hashMap!=null) {
properties = new ArrayList<MuteModel>(hashMap.values());
for (MuteModel muteModel:properties){
muteModel.setIsgroup(YES);
}
}else{
properties = new ArrayList<MuteModel>();
}
MyChat.muteModelList.addAll(properties);
Gson gson = new Gson();
String strMuteList = gson.toJson(MyChat.muteModelList);
editSharedPref(MUTELIST,strMuteList);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
in your case I think the generic adapter of ingredients will look like as follows
GenericTypeIndicator<ArrayList<Ingredients>>
& in case of pasos you can do like
GenericTypeIndicator<ArrayList<Strings>>

Categories

Resources