I am developing and Android app and want to save to a local SQLite Database and then want it to sync with Firebase, I have gotten the Firebase sync working I am only having the problem saving to the local database, the app crashes when I click save however the data gets stored in firebase but not in the local SQLite. I have included my code below if anyone can assist.
buttonSave.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Creating firebase object
Firebase ref = new Firebase(Config.FIREBASE_URL);
ref.keepSynced(true);
//Getting values to store
String name = editTextName.getText().toString().trim();
String address = editTextAddress.getText().toString().trim();
String venue = editVenue.getText().toString().trim();
String DateTime = editDateTime.getText().toString().trim();
//Creating Person object
final MeetingUser person = new MeetingUser();
//Adding values
person.setName(name);
person.setAddress(address);
person.setVenue(venue);
person.setDateTime(DateTime);
//Storing values to firebase
ref.push().setValue(person);
//Write to local SQL database
boolean isInserted = DB.SaveUserMeetings(editTextName.getText().toString(),
editDateTime.getText().toString(),
editVenue.getText().toString(),
editTextAddress.getText().toString());
if (isInserted == true)
Toast.makeText(Capture_Meetings.this, "Data Not Saved", Toast.LENGTH_SHORT).show();
else
Toast.makeText(Capture_Meetings.this, "Data Saved", Toast.LENGTH_SHORT).show();
//Value event listener for realtime data update
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
//Getting the data from snapshot
MeetingUser person = postSnapshot.getValue(MeetingUser.class);
//Adding it to a string
String string = "Name of School: " + person.getName() + "\n Date:" + person.getDateTime() + "\n Venue:" + person.getVenue() + "\nMeeting Notes: " + person.getAddress() + "\n\n";
//Displaying it on textview
textViewPersons.setText(string);
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
System.out.println("The read failed: " + firebaseError.getMessage());
}
});
}
});
}
My Error log
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.pooveshin.saica_sgb, PID: 10770
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean com.example.pooveshin.saica_sgb.DatabaseHelper.SaveUserMeetings(java.lang.String, java.lang.String, java.lang.String, java.lang.String)' on a null object reference
at com.example.pooveshin.saica_sgb.Capture_Meetings$3.onClick(Capture_Meetings.java:114)
at android.view.View.performClick(View.java:4780)
at android.view.View$PerformClick.run(View.java:19866)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Have you considered using Firebase offline capabilities (https://firebase.google.com/docs/database/android/offline-capabilities) ...enabled by calling following
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
Related
Fatal Exception: java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
at com.drriyadh.lab.ui.activity.OrdersActivity$1.onEvent(OrdersActivity.java:112)
at com.drriyadh.lab.ui.activity.OrdersActivity$1.onEvent(OrdersActivity.java:95)
at com.google.firebase.firestore.Query.lambda$addSnapshotListenerInternal$2(Query.java:1133)
at com.google.firebase.firestore.Query$$Lambda$3.onEvent(:6)
at com.google.firebase.firestore.core.AsyncEventListener.lambda$onEvent$0(AsyncEventListener.java:42)
at com.google.firebase.firestore.core.AsyncEventListener$$Lambda$1.run(:6)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8019)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
Hi guys, i added "addSnapshotListener" i did not using any long in my database or anything like this and i getted this crash
my code:
private void getData() {
orderColRef = FirebaseFirestore.getInstance().collection(XXXXX.XXXXXX);
listenerRegistration = orderColRef.whereEqualTo("XXXXXXX", user.getUid()).addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(#Nullable QuerySnapshot value, #Nullable FirebaseFirestoreException error) {
binding.progressBar.setVisibility(View.GONE);
if (error != null) {
Log.d(TAG, "onEvent: " + error.getMessage());
Utils.showErrorMessage(getString(R.string.XXXX), activity);
return;
}
orders.clear();
for (DocumentSnapshot ds : value) {
HomeOrder order = ds.toObject(HomeOrder.class);
order.setAccepted(ds.getBoolean("XXXXXXXX"));
homeOrders.add(order);
}
adapter.notifyDataSetChanged();
}
});
}
private void prepareRecyclerView() {
binding.rvOrders.setHasFixedSize(true);
adapter = new OrdersAdapter(homeOrders, context);
}
this is everything from line 95 to 112
my firestore database did not have any long
and in the model class i just have one int
but this is crash did not show all the time
some time it gone and some time it back
but i did not did any change in this time
Numbers in Firestore are usually interpreted as Long when converting them to Java. So you should change the Integer you have in your HomeOrder class to a Long to ensure the Firestore mapping code can set it correctly.
Dear Friends,
I am accessing data from a Firebase database, however I am unable to get a list of my data.
I am getting the following exception:
E/UncaughtException: com.google.firebase.database.DatabaseException: Can't convert object of type java.util.ArrayList to type com.sg.rapid.Models.AlaramData`
here is my code:
mDatabaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
AlaramData usersList = dataSnapshot.getValue(AlaramData.class);
String name = usersList.getStatus();
childList.add(usersList);
// here you can access to name property like university.name
}
Log.d("", "Value is: " + childList);
//Create a List of Section DataModel implements Section
sections.add(new SectionHeader(childList, "2018", 1));
adapterRecycler.notifyDataSetChanged();
}
Thanks in advance.
Reading the error message, we can understand that the method is returning an ArrayList of your elements, then I noticed you used the wrong variable there.
It should be using postSnapshot instead of dataSnapshot. Try this:
AlaramData usersList = postSnapshot.getValue(AlaramData.class);
I have solved the issue by changing the json structure in firebase database.
the code as follows:
// Read from the database
mDatabaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
Log.d("", "onChildChanged:" + dataSnapshot.getKey());
sections.clear();
childList.clear();
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
AlaramData alaramData = postSnapshot.getValue(AlaramData.class);
int x = 0;
// here you can access to name property like university.name
childList.add(alaramData);
}
Log.d("", "Value is: " + childList);
//Create a List of Section DataModel implements Section
sections.add(new SectionHeader(childList, "2018", 1));
adapterRecycler.notifyDataChanged(sections);
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w("", "Failed to read value.", error.toException());
}
});
I am reading the data from the firebase database.Following is snapshot of the data stored in database.
In the snap string starting with "8SS..." is the uid of the user. Following is the code for retrieving the data from firebase database.
//To check if uid of current user and database user matches.
Query q = FirebaseDatabase.getInstance().getReference().child("Location").child(user.getUid()).equalTo(FirebaseAuth.getInstance().getCurrentUser().getUid());
q.addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot singleSnapshot : dataSnapshot.getChildren()){
Log.d(TAG, "Yay!!");
User us = singleSnapshot.getValue(User.class);
String string = "Name: "+ us.getName()+"\nAddress: "+ us.getlat()+ us.getlon()+ "\n\n";
n.setText(string);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
// read query is cancelled.
Log.d(TAG, "loadPost:onCancelled", databaseError.toException());
}
});
User class contains getters and setters.
The error is that only empty Text View appears concluding reading from database fails.
How to evaluate if query is true or false?
What is the error while reading from ValueEventListener()?
I tried using this:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Location").child("8SS0uk4FmiPUtXP208Tx8Cqxt2z2");
And then calling on ref.addListenerForSingleValueEvent() but still nothing gets displayed.
I tried using this:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Location").child(user.getUid());
This gives dataSnapShot : "DataSnapshot={key='-Kn...', value="latitude:.., longitude:..., Name:..."}. But this is not how I expected it to be.
The database structure should have been Location --> Uid --> Name : "Jane", .. .
This is my code for inserting data in the database.
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser() ;
refDatabase = FirebaseDatabase.getInstance().getReference().child("Location").child(user.getUid());
DatabaseReference newPost = refDatabase.push();
//the push() command is already creating unique key
Map<String, String> mapname = new HashMap<String, String>();
mapname.put("Name", n.getText().toString());
mapname.put("latitude", Double.toString(lat));
mapname.put("longitude", Double.toString(longt));
mapname.put("user id", user.getUid());
newPost.setValue(mapname);
I solved this question by introducing multiple for loops.
So, the snapshot of my first child was dataSnapShot : "DataSnapshot={key='-Kn...', value="latitude:.., longitude:..., Name:..."}.
Below is the code to extract all the values and keys :
mRef.addValueEventListener(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d(TAG, "Children" + dataSnapshot.getKey());
for(DataSnapshot singleSnapshot : dataSnapshot.getChildren()){
String st = singleSnapshot.getKey();
Log.d(TAG, "Yay!!" + singleSnapshot.child(st));
st = "";
int count=0;
for(DataSnapshot singleSnap : singleSnapshot.getChildren()) {
Log.d(TAG, "String" + singleSnap.getValue());
//n.setText(us.getName());
if(count==0) {
st = "Name: " + singleSnap.getValue() + '\n';
}
else if(count==1) {
st = st + "Latitude: " + singleSnap.getValue() + '\n';
}
else if(count==2) {
st = st + "Longitude: " + singleSnap.getValue() + '\n';
}
count++;
}
final TextView rowTextView = new TextView(Menu5.this.getActivity());
rowTextView.setText((CharSequence) st);
ll.addView(rowTextView);
}
}
This gives single key and value pair for every unique id of created by push.So, I had to hard code the concatenation and display as the structure will remain same throughout the app.
Why are you using equal to and then getting the current user. .child(user.getUid()) should already be your current user which gives you the value of the child you are trying to listen to.
I think the uuid's are the children of "8SSOuk.......".
So it should look something like this:
FirebaseDatabase.getInstance().getReference().child("Location").child("8SSOuk.......").child(user.getUid());
I'm having some issues reading from a Firebase Database.
I have a pretty simple layout
{
"lot" : {
"lot1" : "low",
"lot2" : "low",
"lot3" : "low"
}
}
Of course MyAppName { } is above this all.
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getInstance().getReference();
// Read from the database
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
lotMap = (HashMap) dataSnapshot.getValue();
Log.d("[Directions Activity]: ", "Lot1 value ====== " +lotMap.get("lot"));
Iterator it = lotMap.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
Log.d("[Directions Activity]: ", "iterator " + pair.getKey() + " = " + pair.getValue());
System.out.println();
it.remove(); // avoids a ConcurrentModificationException
}
}
Here's what returns from log
D/[Directions Activity]:: Lot1 value ====== null //null obviously
//because key lot1 doesn't exist
D/[Directions Activity]:: lot = {lot3=low, lot2=low, lot1=low}
So to me, it looks like it's returning the string {lot3=low, lot2=low, lot1=low}, but I'd like to be able to get an array, with each value if possible.
Is this achievable??
I had the same question and this is what i used. Modifying to fit the question here
private List<String> lotList;
lotList = new ArrayList<>();
DatabaseReference reference= database.getInstance().getReference().child("lot");
Now adding value event listener
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Iterable<DataSnapshot> mData = dataSnapshot.getChildren();
for(DataSnapshot d : mData){
String lot_string = d.getValue(String.class);
lotList.add(lot_string);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
There's some tweak in your code. Your
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getInstance().getReference();
should be write like this,
DatabaseReference myRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference database = myRef.child("anyValueNameYouSpecifyInConsole");
Those 2 lines should be declare outside onCreate method. The one that you need to specify with addValueEventListener is the 2nd DatabaseReference, not the first one. So, it should looks like this from my example,
database.addValueEventListener (new ValueEventListener)
and it will import method.
If you wish the data to be displayed in a particular TextView, then just findViewById the TextView you wanna use and include it in onDataChange method like so,
String x = dataSnapshot.getValue(String.class);
textViewNameDeclared.setText(x);
And don't forget to change the security rule for reading.
you can use typecast to JSONObject and parse the JSONObject
JSONObject jsonObject= new JSONObject((Map)dataSnapshot.getValue());
JSONObject jsonObj= (JSONObject) jsonObject.get("lot");
for (Object key : jsonObj.keySet()) {
//based on you key types
String keyStr = (String)key;
Object keyvalue = jsonObj.get(keyStr);
//Print key and value
System.out.println("key: "+ keyStr + " value: " + keyvalue);
}
if you using java 8 than you use lamada expression.
I am using Firebase for both authentication and realtime database. My authentication code was successfully run also my enter value to database code also run, but when I am coding for fetch value in database, I am getting run time error trying to enter value at Firebase database:
FATAL EXCEPTION: main
Process:com.xxx.xxx, PID: 22601
com.google.firebase.database.DatabaseException: Invalid Firebase Database
path: https://xxx-exxe.firebaseio.com/. Firebase Database paths must not contain '.', '#', '$', '[', or ']'
My Code is :
final FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference reference = database.getReference("https://korsa-e03ae.firebaseio.com/");
reference.addValueEventListener(new com.google.firebase.database.ValueEventListener() {
#Override
public void onDataChange(com.google.firebase.database.DataSnapshot dataSnapshot) {
Offerride user = dataSnapshot.getValue(Offerride.class);
if (user == null){
Toast.makeText(getContext(),"User data is null!",Toast.LENGTH_LONG).show();
return;
}
tvsource.setText(user.source + " , " + user.destination + " , " + user.startDate + " , " + user.startTime);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(getContext(), "Failefddd", Toast.LENGTH_LONG).show();
}
});
I think the answer is quite obvious you don't need to specific the url because app is already link to the database when you set up the project
just change from
DatabaseReference reference = database.getReference("https://korsae03ae.firebaseio.com/");
to
DatabaseReference reference = database.getReference();
Then it should work
Url of your database is in your google-services.json file.
By firebase docs https://firebase.google.com/docs/database/admin/retrieve-data to read data, you can do the following:
final FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("posts");
// Attach a listener to read the data at our posts reference
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Post post = dataSnapshot.getValue(Post.class);
System.out.println(post);
}
#Override
public void onCancelled(DatabaseError databaseError) {
System.out.println("The read failed: " + databaseError.getCode());
}
});
Instead of using getReferance use, getReferanceFromUrl.
and in your case: database.getReference.child("posts");