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?
Related
I am trying to get data using model class but in vain. There are so many questions have already been asked, but I think I am according to them, If I am missing something, Please let me know..
I am trying to get data something like this..
FirebaseHelper.firebaseDatabase().getReference().child("rooms").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot roomSnap : dataSnapshot.getChildren()) {
Room room = roomSnap.getValue(Room.class);
//no response
Log.d("createdAt", room.createdAt);
// returns all data in roomSnap
Log.d("roomSnap", roomSnap.toString());
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
But its not fetching data from database.
Database:
Room Model
public class Room implements Parcelable {
private static final String TAG = "Room";
public Room() {
}
public String objectID = "";
public String createdAt = "";
public String updatedAt = "";
public String ACL = "";
public String roomNumber = "";
public String roomStatus = "";
public String roomGuestFirstName = "";
public String roomGuestLastName = "";
public String guestArrival = "";
public String guestDepature = "";
protected Room(Parcel in) {
objectID = in.readString();
createdAt = in.readString();
updatedAt = in.readString();
ACL = in.readString();
roomNumber = in.readString();
roomStatus = in.readString();
roomGuestFirstName = in.readString();
roomGuestLastName = in.readString();
guestArrival = in.readString();
guestDepature = in.readString();
}
public static final Creator<Room> CREATOR = new Creator<Room>() {
#Override
public Room createFromParcel(Parcel in) {
return new Room(in);
}
#Override
public Room[] newArray(int size) {
return new Room[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(objectID);
dest.writeString(createdAt);
dest.writeString(updatedAt);
dest.writeString(ACL);
dest.writeString(roomNumber);
dest.writeString(roomStatus);
dest.writeString(roomGuestFirstName);
dest.writeString(roomGuestLastName);
dest.writeString(guestArrival);
dest.writeString(guestDepature);
}
}
I am using same class to creating room and that's working fine, just I am getting issue in data retrieving. Even there is no error and nothing in logcat,
It was my stupidity I was trying to get data from empty String. I was expecting at least Log-cat tag name, however I have solved this, just adding data to value like this...
I think the problem with your code is that you are not setting the retrieved data to a list or recycler view(anything that you are using to show data) and if this doesn't help try setting your addvalue event listener like mine in the below code.
i hope this will help you.
DatabaseReference ref = database.getReference().child("buddy_plans");
ref.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Buddy buddy = dataSnapshot.getValue(Buddy.class);
listBuddy.add(buddy);
buddyAdapter.notifyDataSetChanged();
}
#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) {
}
});
Ok so I've been looking for related articles regarding this, I've made a few experiments but I can't understand why I can't still get the values of note, date_time and vaccine objects... I'm planning on putting them in a ListView and I already got the key from the list of data using ChildEventListener
lastlastref = myRef.child(babyid).child("baby_features").child("immunization_records");
lastlastref.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
String string = dataSnapshot.getValue(String.class);
}
#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) {
}
});
and then I've tried using EventListener to get the values inside of it
lastlastref = myRef.child(babyid).child("baby_features").child("immunization_records");
lastlastref.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
String string = dataSnapshot.getValue(String.class);
DatabaseReference newRef = lastlastref.child(string);
newRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
note = snapshot.child("note").getValue(String.class);
vaccine = snapshot.child("vaccine").getValue(String.class);
timestamp = snapshot.child("date_time").getValue(String.class);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
arrayList.add(vaccine + "" + timestamp + "" + note);
adapter.notifyDataSetChanged();
}
#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) {
}
});
But the app still crashes and logcat says "Can't pass null for argument 'pathString' in child()"
You set up your reference to:
lastlastref = myRef.child(babyid).child("baby_features").child("immunization_records");
So each child node under this location is a JSON object like this:
{
"date_time": "November/16/2018...",
"note": "hhjj...",
"vaccine": "Measles"
}
But in your onChildAdded, you're trying to retrieve a single string value. Since the above JSON object is not a single string value, the getValue(String.class) returns null.
To get the values, you can call getValue() on the individual properties:
lastlastref.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
String date_time = dataSnapshot.child("date_time").getValue(String.class);
String note = dataSnapshot.child("note").getValue(String.class);
String vaccine = dataSnapshot.child("vaccine").getValue(String.class);
}
You can also create a minimal class to wrap each record, and read that. The simplest version of that is:
public class ImmunizationRecord {
public String date_time;
public String note;
public String vaccine;
}
And the reading would then be done with:
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
String record = dataSnapshot.getValue(ImmunizationRecord.class);
}
A small side note about the way you store date_time. This format will lead to problems as you progress, since it is not sortable. If you need to store time stamps, store them as milliseconds since the epoch, or in a string format that allows them to be sorted (e.g. 2018-11-16T11:29:00).
I am implementing Firebase and DataSnapshot return null to custom java object. I have try to solved this issue by following some answer using this site also but I don't know where is exact issue in my code.
Here I am attaching my screenshot of firebase database so kindly help me resolve this issue
Below is my model.
public class ChatModel {
private String messege;
private String user;
private int intType;
public ChatModel(){}
public ChatModel(String messege, String user, int intType) {
this.messege = messege;
this.user = user;
this.intType = intType;
}
public String getMessege() {
return messege;
}
public void setMessege(String messege) {
this.messege = messege;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public int getIntType() {
return intType;
}
public void setIntType(int intType) {
this.intType = intType;
}
}
and here is my activitycode.
DatabaseReference messagesReference = reference1.child("messages/"+ UserDetails.username + "_" + UserDetails.chatWith);
Log.e("messages URL "," ==>"+messagesReference);
messagesReference .addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Log.e("messages Referencev "," ==>"+dataSnapshot.toString());
ChatModel map = dataSnapshot.getValue(ChatModel.class);
String message = map.getMessege();
String userName = map.getUser();
Log.e("message "," ==>"+message); // Here I am getting null value
}
#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) {
}
});
and logcat show message like this.
==>DataSnapshot { key = -KslrqBPRMNKkWQO15h_, value = {message=Hi This is sakib, user=sakib} }
Your keys are mismatch that's why it's returning null value check your screenshot and your ChatModel class, remove str from your ChatModel class variables, and generate getter setter again
This might help you.
public class ChatModel {
private String messege;
private String user;
private int intType;
// TODO generate getter setter again
}
either you can get values via map as well
Map<String,String> map=(Map<String,String>)dataSnapshot.getValue();
String message = map.get("message");
String userName = map.get("user");
Log.e("message "," ==>"+message);
Try to rename your model
private String message;
public String getMessage(){ return message;}
i had the same issue and it worked after i named the properties exactly like they are named in the firebase Database.
You can try to use dataSnapshot.getChildren() in the for loop, like this:
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
if (dataSnapshot.exists()) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
ChatModel map = snapshot.getValue(ChatModel.class);
String message = map.getMessege();
String userName = map.getUser();
}
}
I have two children in a Firebase database like 1) Semester I Notes and 2) Semester II Notes.
I have successfully uploaded data into these children, but when I retrieve these items, it just returns the first child's data. Code for Firebase helper here - name is the variable of our Semester I Notes or Semester II Notes
public class FireBaseHelper {
DatabaseReference db;
boolean saved;
String name;
Query myref;
ArrayList<Semester> semesters = new ArrayList<>();
public FireBaseHelper(DatabaseReference db, String n) {
this.db = db;
myref=db.orderByChild("model").equalTo(n);
name = n;
}
public boolean save(Semester s) {
if (s == null) {
saved = false;
} else {
try {
db.child(name).push().setValue(s);
myref=db.orderByChild("model").equalTo(name);
} catch (DatabaseException e) {
e.printStackTrace();
saved = false;
}
saved = true;
}
return saved;
}
public void fetchData(DataSnapshot dataSnapshot) {
Log.i("Getchildcount", String.valueOf(dataSnapshot.getChildrenCount()));
semesters.clear();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
Semester semester = ds.getValue(Semester.class);
semesters.add(semester);
}
}
public ArrayList<Semester> retrieve() {
myref.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
return semesters;
}
}
I call the retrieve method like this
Firebase helper = new FireBaseHelper(db, NameOfDb);
NotesAdapter adapter = new NotesAdapter(this, helper.retrieve());
//this is the list variable noteItem and I set adapter on it
notesItem.setAdapter(adapter);
Model Image of Firebase
You need to use DatabaseReference childItem = mDatabase.child("child_item_name");
Firebase Realtime database Doc
All data.getValue() are returning null. I can get child key to return fine. I can write to firbase fine. Just data.getValue is returning null for some unknown reason. I have other classes working fine using the exact same format.
//method for retrieving info from firebase which has notifications
private void retrieveInfo(){
Firebase ref = new Firebase("https://fitnectapp.firebaseio.com/");
// Attach an listener to read the data at our posts reference
ref.addChildEventListener(new ChildEventListener() {
// Retrieve new posts as they are added to the database
#Override
public void onChildAdded(DataSnapshot snapshot, String previousChildKey) {
getUpdates(snapshot);
}
#Override
public void onChildRemoved(DataSnapshot snapshot) {
getUpdates(snapshot);
}
#Override
public void onChildChanged(DataSnapshot snapshot, String previousChildKey) {
getUpdates(snapshot);
}
#Override
public void onChildMoved(DataSnapshot snapshot, String previousChildKey) {
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
}
//All data values returning null??
private void getUpdates(DataSnapshot ds) {
if (ds.getKey().equals("notifications")) {
for (DataSnapshot data : ds.getChildren()) {
String user = sp.getString("username", null);
Notification notification = data.getValue(Notification.class);
if(notification.getNotifUser().equals(user)){
String sender = notification.getNotifSender();
String workout = notification.getNotifWorkout();
String notificationTxt = sender + " has liked your workout, " + workout;
notifications.add(notificationTxt);
}
}
}
}