This is my code and I am uploading a student name and batch name to firebase database. This method is excecuted after user created the account successfully.
User is created in Authentication but data is not uploaded to database and the only error in logcat is:
E/SpellCheckerSession: ignoring processOrEnqueueTask due to unexpected mState=TASK_CLOSE scp.mWhat=TASK_CLOSE
private void uploadUserDetails(){
String name = studentName.getText().toString();
String batch = "BCA";
database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference(firebaseAuth.getUid());
Student student = new Student(name,batch);
ref.child("Student Details").setValue(student);
}
public class Student {
public String name;
public String batch;
Student(){
this.name= "Hello";
this.batch="Unspecified";
}
Student(String name,String batch){
this.name=name;
this.batch=batch;
}
}
The following snippet uses a map for storing the student name and his batch, in this map key is string and value is of object type. and putting a value of key "l".
Map<String, Object> updates = new HashMap<>();
updates.put("l", Arrays.asList(student.batch,student.name));
ref.child("Student Details").setValue(updates);
Related
I am using this method to store data in my firebase database:
First i store all the data in a Model Class, called SubjectDataModel,
then i get the push key from the firebase database.
and then i set value to that particular key.
Here is my code :
SubjectDataModel:
public class SubjectDataModel {
public String id;
public String dbName;
public String subName;
public String tagline;
public int preference;
public SubjectDataModel()
{
}
public SubjectDataModel(String id, String dbName, String subName, String tagline, int preference) {
this.id = id;
this.dbName = dbName;
this.subName = subName;
this.tagline = tagline;
this.preference = preference;
}
}
Then i use the following code to push it to the database and then i also store the key id locally.
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Data");
String id = ref.push().getKey();
SubjectDataModel newSub = new SubjectDataModel(id, txt_dbName, txt_subName, txt_tagline, txt_preference);
ref.child(id).setValue(newSub);
Now imagine, later in time, i want to update this data,
so i have the key id stored, so i can access it, i also have edited all the other data locally, so now if i make a SubjectDataModel Object with that data and again do ref.child(id).setValue(newSub); with the stored id, will the data be updated ? Or is there any other method to do so ?
updateChildren() is the method you are looking for, refer this documentation Firebase Read and Write Data on Android
Here's an example from documentation...
private void writeNewPost(String userId, String username, String title, String body) {
// Create new post at /user-posts/$userid/$postid and at
// /posts/$postid simultaneously
String key = mDatabase.child("posts").push().getKey();
Post post = new Post(userId, username, title, body);
Map<String, Object> postValues = post.toMap();
Map<String, Object> childUpdates = new HashMap<>();
childUpdates.put("/posts/" + key, postValues);
childUpdates.put("/user-posts/" + userId + "/" + key, postValues);
mDatabase.updateChildren(childUpdates);
}
Okay, so i tried this and it works perfectly, like i expected it to. No need for me to use maps or anything. Simplest way to update data.
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Data");
SubjectDataModel newSub = new SubjectDataModel(idForUpdate, txt_dbName, txt_subName, txt_tagline, txt_preference);
ref.child(idForUpdate).setValue(newSub);
So here basically, i created the object with the required data, and pushed it back to the same id with which i created a node in the firebase database, so it updates that same node with the new values.
I created a family tree application on java and mysql database. Now I am testing an android app for the same. So I converted my mysql database file to JSON format and uploaded it to firebase. When I am inserting records on it, it is working perfectly fine but when I try to fetch the data it is showing the error:
com.google.firebase.database.DatabaseException: Failed to convert a value of type java.lang.String to int
at com.google.android.gms.internal.firebase_database.zzkt.zzb(Unknown Source:180)
What should be the problem? I tried deleting the data from the database which I uploaded through JSON file and then inserted records directly from app into database and fetch them, it worked fine but when I am adding record from JSON file only then It is creating problem.
here is the code from the app for fetching data:
public void clicked(){
mDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<Family> FamilyList = new ArrayList<>();
for (DataSnapshot adSnapshot: dataSnapshot.getChildren()) {
Family f = adSnapshot.getValue(Family.class);
FamilyList.add(f);
// adsList.add(adSnapshot.getValue(Family.class));
}
Toast.makeText(MainActivity.this, "Total Records: "+FamilyList.size(), Toast.LENGTH_SHORT).show();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Family Model Class:
public class Family {
int id;
String name;
String fatherName;
int fid;
String city;
String state;
public Family(int id, String name, String fatherName, int fid, String city, String state) {
this.id = id;
this.name = name;
this.fatherName = fatherName;
this.fid = fid;
this.city = city;
this.state = state;
}
public Family()
{
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getFatherName() {
return fatherName;
}
public void setFatherName(String fatherName) {
this.fatherName = fatherName;
}
public int getFid() {
return fid;
}
public void setFid(int fid) {
this.fid = fid;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
Here is the JSON Record Sample
It is the records which I entered through App
I think the converted JSON treated id and fid as String, while in mySQL they are int. (am I correct?)
Tell me if any other code is needed.
The problem relies on here
Family f = adSnapshot.getValue(Family.class);
you are trying to get data in an inappropriate type.
You should correct this by checking Family.class and check if the values there are the same as they are in your database structure in firebase, it will be helpful if you put your database structure here, or some images.
Check if for example in Family.class you have in your variable types the same as they are in firebase, with the same name also.
So for example if in firebase there is an string called name you should have in your constructor inside Family.class the same type and name.
String name;
and in Firebase your json key should be name too.
For instance, check this
your Family class for example should have the variables with the same name and type as your database.
Also check, if the value in firebase has "" is an String type and in your POJO you should have a variable with the type String for what you are trying to access, but if the value dosnt have "" it should be a long , int, double or any type of number.
EDIT: check this structure
It has all the values types as String, but in your Family.class you have the values right for this type of structure.
you should change your database at firebase so all your types matches with the ones in your Family.class, either way it won't fetch your values
Note: if you want to fetch all your values like they are at the first image, just change in Family.class from this:
int id;
String name;
String fatherName;
int fid;
String city;
String state;
to this:
String id;
String name;
String fatherName;
String fid;
String city;
String state;
Also change your constructor types and everything to match all Strings
The thing is that firebase creates unique IDs for each element in your database structure, and the types imported from your MySQL database are not the same as the firebase ones, I suggest you to either change your Family.class variable types as I mentioned above, or replicate your MySQL database with firebase and the same variable types.
This is happening because you have a variable of integer datatype in your model but you are returning String from Firebase... either convert your variable to string or return integer from firebase....
Both model and Firebase variable should be of a same data type.
As per your below error:-
com.google.firebase.database.DatabaseException: Failed to convert a value of type java.lang.String to int at com.google.android.gms.internal.firebase_database.zzkt.zzb(Unknown Source:180)
I think, you need to check somewhere you tried to store value in int which is store in firebase in string.
So first check it and if necessary to cast then casting your value using Integer.parseInt or Integer.valueof
for example,
Integer.valueOf(dataSnapShot.getValue());
or
Integer.parseInt(dataSnapShot.getValue());
For more understanding this you can also refer stack overflow's below links:
Firebase DatabaseException: Failed to convert value of type java.lang.Long to String
com.google.firebase.database.DatabaseException: Failed to convert a value of type java.lang.String to double
Firebase android error "Failed to convert value of type "
The application I'm developing is really similar to Instagram.
On Instagram, users can change their usernames anytime. And if you change your username, your posts also show the updated username.
How can I implement this on a firebase database environment?
For example, I have VO below.
#IgnoreExtraProperties
public class Post {
String uid;
String username;
String content;
int likesCount = 0;
Map<String, Boolean> likes = new HashMap<>();
Map<String, Boolean> hashtags = new HashMap<>();
public Post() {
// Default constructor required for calls to DataSnapshot.getValue(Post.class)
}
public Post(String uid, String username, String content) {
this.uid = uid;
this.username = username;
this.content = content;
}
#Exclude
public Map<String, Object> toMap() {
HashMap<String, Object> result = new HashMap<>();
result.put("uid", uid);
result.put("username", username);
result.put("content", content);
result.put("likesCount", likesCount);
result.put("likes", likes);
result.put("hashtags", hashtags);
return result;
}
}
If I include "username" in the Post Object, I can show each post with the usernames synchronously, but it will be difficult to show the latest updated "username" all the time.
If one user's Posts are over 1000, should I update all the posts at the same time when the username is changed?
If I exclude "username" in Post object I can load updated "username" asynchronously each time after any Post is loaded.
Or at the first time just show old username, and check if it is changed everytime when the Post is loaded, and update it asynchronously.
Which is the most efficient and proper way to implement for it?
I am using Firebase Database in an Android application, and everytime a user is registred I store some values in the database for this purpose I am doing what follows:
database = FirebaseDatabase.getInstance();
DatabaseReference mRef = database.getReference().child("Users").push();
FirebaseUser user = mAuth.getCurrentUser();
String userId = user.getUid();
mRef.child("User").child("age").setValue(selectedAge);
mRef.child("User").child("gender").setValue(finalGender);
mRef.child("User").child("userId").setValue(userId);
mRef.child("User").child("username").setValue(username);
but when I go to my firebase console I see that a kind of id is automaticaly generated which I do not need since as you can see in the image I set my own id.
Is there a way to avoid this, and create nodes like the second User node in the image ??
NOTE: the second user node i added it manualy
To directly answer your question here is the change I'd suggest:
FirebaseDatabase database = FirebaseDatabase.getInstance();
FirebaseUser user = mAuth.getCurrentUser();
String userId = user.getUid();
DatabaseReference mRef = database.getReference().child("Users").child(userId);
mRef.child("age").setValue(selectedAge);
mRef.child("gender").setValue(finalGender);
mRef.child("username").setValue(username);
I'd also suggest that you create a Java class to represent whatever user data you want to store in your database. Taking advantage of Firebase's ability to read/write to your database using Java classes will make those operations much easier. For example you add a User class to your project like the following:
public class User {
public double age;
public String gender;
public String userName;
//required default constructor
public User() {
}
public User(double age, String gender, String userName) {
this.age = age;
this.gender = gender;
this.userName = userName;
}
public double getAge() {
return age;
}
public void setAge(double age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
By using a java class to write to your database you can update your write operation like so:
FirebaseDatabase database = FirebaseDatabase.getInstance();
FirebaseUser user = mAuth.getCurrentUser();
String userId = user.getUid();
User user = new User(26, "M", "user001");
DatabaseReference mRef = database.getReference().child("Users").child(userId);
mRef.setValue(user);
Notice there is no field to the store user's uid in the Java object. This is up to you but I did not include it for two reasons. First, in the database we are using the user's uid as the key to store there data in a unique location. Second, since you are using Firebase Authentication, in your app if you need to get the id of the currently signed in user you can access it via FirebaseAuth.
Just change this line:
DatabaseReference mRef = database.getReference().child("Users").push();
to this:
DatabaseReference mRef = database.getReference().child("Users");
The push() automatically adds a unique key.
I am pretty much aware of the absence of foreign keys in Realm. But I encountered this issue. I receive data in a normalised way and I have to figure out how to properly persist the relations.
Example:
class User{
private int id;
private Email email;
}
class Email{
private int id;
private String address;
}
And I receive something like:
{user={id:1, emailId:1}}
How can I store this type of data in my existing realm object ?
You will have to parse the JSON yourself to setup the links. From your description it isn't clear if you User and Email is already in Realm, but if that is the case I would do something like this:
class User{
#PrimaryKey
private int id;
private Email email;
}
class Email{
#PrimaryKey
private int id;
private String address;
}
JSONObject json = new JSONObject("{id:1, emailId:1}");
realm.beginTransaction();
User user = realm.where(User.class).equalTo("id", json.getInt("id")).findFirst();
Email email = realm.where(Email.class).equalTo("id", json.getInt("emailId")).findFirst();
user.setEmail(email);
realm.commitTransaction();