realm1.beginTransaction();
newuser tripnew = realm1.createObject(newuser.class);
int nid= (int)(realm.where(newuser.class).max("nid").intValue()+1);
tripnew.setNid(nid);
tripnew.setFrom(frominput.getText().toString());
tripnew.setTo(toinput.getText().toString());
tripnew.setDatejourney(dateinput.getText().toString());
realm1.commitTransaction();
updatetrip();
/// iam also use this code not working
realm.where(newuser.class).maximumInt("id_cp") + 1;
newuser.java//////
public class newuser extends RealmObject {
private String from,to,datejourney;
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public String getDatejourney() {
return datejourney;
}
public void setDatejourney(String datejourney) {
this.datejourney = datejourney;
}
}
It looks that your class doesn't have nid nor id_cp numeric field. Add int nid; field along with accessors and then realm.where(newuser.class).max("nid").intValue()+1 should work in most of the cases. However it will fail if there is no newuser instance in database yet. I use singleton factory for generating primary keys as a more generic solution.
There is a long discussion in Realm Git Hub if you need more context: Document how to set an auto increment id?
Related
I am trying my hands on Firebase for the first time and I ran into kind of a problem.
Getting data out of my Firebase storage/database only works if the getter method fits the variable name or the member variables are public. But my naming convention for member variables is mVariableName and i leave that "m" out of my getter methods name. Now I have multiple questions:
Is making the model member variables public a viable option or is that bad practice?
What is the best approach here for naming? Should i name the getter methods getmName or should i leave the "m" out of the member variable names? Should I then change it for the whole project or just for this class?
I just want to know what the best practices are here.
This is the class that reads the entries:
public class ImagesActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private ImageAdapter mAdapter;
private FirebaseStorage mFirebaseStorage;
private DatabaseReference mDatabase;
private List<Upload> mUploads;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_images);
mRecyclerView = findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mUploads = new ArrayList<>();
mFirebaseStorage = FirebaseStorage.getInstance();
mDatabase = FirebaseDatabase.getInstance().getReference(Constants.DATABASE_PATH_UPLOADS);
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
Upload upload = postSnapshot.getValue(Upload.class);
Log.i("UPLOAD", "Upload : " + upload.getName());
mUploads.add(upload);
}
mAdapter = new ImageAdapter(getApplicationContext(), mUploads);
mRecyclerView.setAdapter(mAdapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
And these are the rules:
Database:
{
"rules": {
".read": true,
".write": true
}
}
Storage:
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if true;
}
}
}
And the Upload.class (only works if either fields are public or getter method names fit m-convention, which is ugly):
public class Upload {
public String mName;
public String mImageUrl;
public Upload() {
}
public Upload(String name, String imageUrl) {
if (name.trim().equals("")) {
name = "No Name";
}
mName = name;
mImageUrl = imageUrl;
}
public String getName() {
return mName;
}
public String getImageUrl() {
return mImageUrl;
}
}
The best practice is to use a standard POJO, or Plain Old Java Object. If you do that, Firebase will get out of your way:
public final class User {
// These names don't matter since they are private, you could call it `glubustufo` 😁
// They should always be private
private String mName;
private String mEmail;
// ...
// Constructors
// Methods should be public and use the get/set convention where the following
// words are in CamelCase and will be translated to lowerCamelCase in the db.
public String getName() { return mName; }
public void setName(String name) { mName = name; }
public String getEmail() { return mEmail; }
public void setEmail(String email) { mEmail = email; }
// equals, hashCode, toString
}
Edit, use this class:
public final class Upload {
private String mName;
private String mImageUrl;
public Upload() {
// Needed for Firebase reflection
}
public Upload(String name, String imageUrl) {
if (name.trim().equals("")) {
name = "No Name";
}
mName = name;
mImageUrl = imageUrl;
}
public String getName() {
return mName;
}
public void setName(String name) {
mName = name;
}
public String getImageUrl() {
return mImageUrl;
}
public void setImageUrl(String url) {
mImageUrl = url;
}
}
As an alternative to Supercilex' excellent answer, you can also use a class with only public fields (and not getters/setters):
public final class Upload {
public String name;
public String imageUrl;
}
In this situation Firebase will look for (or create) a JSON property that exactly matches the field name, so make sure you capitalize it correctly.
The Firebase client creates an instance of this class by looking for a parameterless constructor. In this trivial class there is no constructor, so the Java/Android compiler will generate a default, parameterless constructor for you. If you add you own constructor, be sure to also add a parameterless one (as in Supercilex' answer).
See also:
How to Convert Firebase data to Java Object...? for an overview of the options when reading/writing the database from Java.
I used FirebaseRecyclerAdapter to get all the childs of "Pro" using a Model class named " Spacecraft" and now I want to retrieve all the candidates into a child of Pro like "1"
I created a public static "candidat" into "Spacecraft" and I used the setters and getters but still the same error
This is my database:
this is the Model Class
public class Spacecraft{
private String name;
private String desc;
private String last;
private candidat candidat;
public Spacecraft.candidat getCandidat() {
return candidat;
}
public void setCandidat(Spacecraft.candidat candidat) {
this.candidat = candidat;
}
public Spacecraft() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getLast() {
return last;
}
public void setLast(String last) {
this.last = last;
}
public static class candidat{
private String info;
private String namecandid;
public candidat(){}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
public String getNamecandid() {
return namecandid;
}
public void setNamecandid(String namecandid) {
this.namecandid = namecandid;
}
}
}
This is my code for FirebaseRecyclerAdapter
#Override
protected void onStart() {
super.onStart();
FirebaseRecyclerAdapter<Spacecraft, candidatviewholder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Spacecraft, candidatviewholder>(
Spacecraft.class,
R.layout.candidat,
candidatviewholder.class,
query){
#Override
protected void populateViewHolder(candidatviewholder viewHolder, Spacecraft model, int position) {
viewHolder.setName1(model.getCandidat().getNamecandid());
viewHolder.setInfo1(model.getCandidat().getInfo());
}
};
rv.setAdapter(firebaseRecyclerAdapter);
}
The error:
No setter/field for key1 found on class com.example.ilyas.evotingapplication.Spacecraft$candidat
I had this error but the above solutions didn't fix it. Hopefully, this alternate solution will help others. If you have that error occur for almost every variable, chances are that you have Proguard enabled and it is removing the un-used getter and setter methods. To fix this, add a line similar to this to your proguard-rules.pro file:
-keep class com.example.yourapp.ObjectClass
where ObjectClass is the name of your java object class that is stored to Firebase.
I think it's just that your data models on Firebase and in Java differ.
In your java class, the Spacecraft class has a candidat field of type Candidat. But, in the database, the candidat field is really a nested object (map), containing one key Key1, which value is a Candidat structure.
So, depending on what did you want to achieve:
if you wanted each spacecraft to have exactly one candidat: save the database object properly, so {info: "info 1", namecandid: "name 1"} is saved directly under candidat field, not one level deeper, so the field has type Candidat in the code.
if you wanted each spacecraft to have a few candidats: instead of private Candidat candidat field, it should be typed Map<String, Candidat>, because that's the type it has in your database screenshot.
Work for me:
-keepclassmembers class com.myPackageName.MyClassName { *; }
I have data in my firebase DB, everything works fine until I try to De-serialize the data.
Error: argument 1 has type io.realm.RealmList, got java.util.ArrayList
Here's my code:
DatabaseReference root = FirebaseDatabase.getInstance().
getReferenceFromUrl("https://swing-8792d.firebaseio.com/playlist");
Query playlistQuery = root.orderByKey().equalTo(key);
playlistQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot child : dataSnapshot.getChildren()) {
Log.d("Child", child + "");
Playlist receivedPlaylist = child.getValue(Playlist.class);
Playlist playlist = new Playlist();
playlist.setCreatedBy(receivedPlaylist.getCreatedBy());
playlist.setName(receivedPlaylist.getName());
playlist.setMyMap(receivedPlaylist.getMyMap());
playlist.setQrKey(receivedPlaylist.getQrKey());
playlist.setCount(receivedPlaylist.getCount());
playlist.setId(receivedPlaylist.getId());
playlist.setTracks(receivedPlaylist.getTracks());
mPlaylist.add(playlist);
}
This is my POJO class:
#RealmClass
public class Playlist extends RealmObject {
String name;
Long id;
RealmList<Track> tracks;
Integer count;
String createdBy;
RealmList<UserMap> myMap;
String qrKey;
public RealmList<UserMap> getMyMap() {
return myMap;
}
public void setMyMap(RealmList<UserMap> myMap) {
this.myMap = myMap;
}
public Playlist(){}
public String getQrKey() {
return qrKey;
}
public void setQrKey(String qrKey) {
this.qrKey = qrKey;
}
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public RealmList<Track> getTracks() {
return tracks;
}
public void setTracks(RealmList<Track> tracks) {
this.tracks = tracks;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getCount() {
return count;
}
public void setCount(Integer count) {
this.count = count;
}
}
If I try to de-serialize with Normal POJO class (i.e Removing Realm) it works fine.
Firebase won't work with classes that do not have default constructor or private variables i.e no public getter/setter.
A easier solution in your case would be to make a middleware class that is the same pojo just not extending RealmObject. Next initialise your RealmObject subclass using the values of the pojo.
Pseudo code
class SimplePojoPlaylist {
public String variable;
}
class Playlist extends RealmObject {
public String variable;
}
Then first cast into SimplePojoPlaylist
for (DataSnapshot child : dataSnapshot.getChildren()) {
SimplePojoPlaylist receivedPlaylist = child.getValue(SimplePojoPlaylist.class);
Playlist playList = new Playlist();
playList.variable = receivedPlaylist.variable;
}
RealmList is not a supported type for deserialization. Your database checks its structure and deduces that tracks should be an ArrayList. Then, when it tries to convert it, it finds that the types do not match.
Check this link from the docs:
Also, it is a good practice to make your objects immutable to avoid unwanted access and/or modifications.
Creating an empty object from scratch and then calling setter methods to define its state is not a very good pattern, because it can create a situation where an object is accessed before when its state is "broken".
If you need to create an object that is flexible, has a few mandatory fields and some optional, consider using the Builder pattern, although to do it you'd have to redesign your model.
wikipedia - Builder
If you don't need/want to use a builder, my advice is:
1) Make the empty constructor private and create another public one that requires all the fields.
2) Change your tracks field to be of type "List". Then, if you need the object to return a RealmList create another getter method such as tracksAsRealmList() that makes a RealmList out of the member list and returns it.
3) Make sure that the "Track" model has an empty private constructor, a public one with all of its parameters and that all of its fields are supported by firebase deserialization.
4) Unless strictly necessary, make your object fields private and set its value through a setter method.
I hope this helps you.
I am creating an application in android and I want to store data of places user selected on the google map. I am currently storing all the places by adding them all in an array and then serialize them by Gson library and it works fine and coding is very simple and easy but if i use data base instead of that that then the coding will be more complex and because implantation of data base is more complex then simply string the array of places to shared preferences. below is the class whose objects are i am storing and saving in the shared preferences but if want to store them on the data base then i have to go through more complex I have to create queries for insert, delete update etc. so suggest me that should i use db or shred preference is good for saving list of places.
package com.example.googlemapstext;
import java.util.ArrayList;
import android.location.Address;
public class MyPlace {
private int id;
private String placeName;
private Address placeAddress;
private int ringerState;
private int brightnessState;
private int wifiState;
private int gpsState;
private int bluetoothState;
private int radiusValueIndex;
private ArrayList<Contact> contactArrayList;
private String message;
private double radiusValue;
private boolean notificationCheck;
public MyPlace(int id,String placeName, Address placeAddress, String radiusValue,
int ringerState, int brightnessState, int wifiState, int gpsState,
int bluetoothState, int radiusValueIndex, ArrayList<Contact> contactArrayList,
String message, boolean notificationCheck) {
this.id=id;
this.placeName = placeName;
this.placeAddress = placeAddress;
this.radiusValue = getTrimedRadiusValue(radiusValue);
this.ringerState = ringerState;
this.brightnessState = brightnessState;
this.wifiState = wifiState;
this.gpsState = gpsState;
this.bluetoothState = bluetoothState;
this.contactArrayList = contactArrayList;
this.message = message;
this.radiusValueIndex = radiusValueIndex;
this.notificationCheck = notificationCheck;
}
private double getTrimedRadiusValue(String radiusValue)
{
radiusValue=radiusValue.replace("Radius ", "");
radiusValue=radiusValue.replace(" Meters", "");
return Double.parseDouble(radiusValue);
}
public boolean getNotificationCheck() {
return notificationCheck;
}
public void setNotificationCheck(boolean notificationCheck) {
this.notificationCheck = notificationCheck;
}
public int getRadiusValueIndex() {
return radiusValueIndex;
}
public void setRadiusValueIndex(int radiusValueIndex) {
this.radiusValueIndex = radiusValueIndex;
}
public int getRingerState() {
return ringerState;
}
public void setRingerState(int ringerState) {
this.ringerState = ringerState;
}
public int getBrightnessState() {
return brightnessState;
}
public void setBrightnessState(int brightnessState) {
this.brightnessState = brightnessState;
}
public int getWifiState() {
return wifiState;
}
public void setWifiState(int wifiState) {
this.wifiState = wifiState;
}
public int getGpsState() {
return gpsState;
}
public void setGpsState(int gpsState) {
this.gpsState = gpsState;
}
public int getBluetoothState() {
return bluetoothState;
}
public void setBluetoothState(int bluetoothState) {
this.bluetoothState = bluetoothState;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public double getRadiusValue() {
return radiusValue;
}
public void setRadiusValue(String radiusValue) {
this.radiusValue = getTrimedRadiusValue(radiusValue);
}
public String getPlaceName() {
return placeName;
}
public void setPlaceName(String placeName) {
this.placeName = placeName;
}
public Address getPlaceAddress() {
return placeAddress;
}
public void setPlaceAddress(Address placeAddress) {
this.placeAddress = placeAddress;
}
public ArrayList<Contact> getContactArrayList() {
return contactArrayList;
}
public void setContactArrayList(ArrayList<Contact> contactArrayList) {
this.contactArrayList = contactArrayList;
}
public int getId() {
return id`enter code here`;
}
public void setId(int id) {
this.id = id;
}
}
The main difference between SharedPreferences and DataBase is like you mentioned :
SharedPreferences works on an Key-Value pair basis. you simply provide the Key and get back the Value you stored. that's great.
DataBase creates an SQLite Tables and you need to use queries to pull them out.
I think that if you are good with the JSON mechanism that you built, then storing a string in SharedPreferences is all you need.
But when the Data get more and more complex, and you would like quick access to any part of it, I think DB would be easier than parsing and seaching a JSON string all the time.
Yes, it might make you write more code for handling the DB queries..
I think SQLite will be better for you. I only use SharePreferences for small, simple and "key - value" structured data. (and it should be like that)
You have a lot of data, so SQLite is the way to go.
Read this for more information : Pros and Cons of SQLite and Shared Preferences
I think answer depends on how many places you want to save and what do you plan to do with them but I consider DB as hte best way to go.
With a DB you will be able to create queries to get only places you want and not load all places in a list and search in it.
To simplify DB creation (and use) you can try orm for Android like OrmLite and GreenDao. I think OrmLite is easier to use than GreenDao (but second one seems to have better performance...) and you can find multiple examples there.
In my opinion, SharedPreferences should only be used for saving user preferences data.
I am trying to sort a list of Facebook contacts in an android app that is using the Facebook API. First part should be contacts that are online (sorted alphabetically) and the second one the offline ones (also sorted alphabetically). So I implemented the Comparable interface and overrode compareTo() in the class for the items that need to be sorted.
public class FBRowItem implements Comparable {
private Bitmap imageId; // pazi bese int, za R.resurs
private String contactName;
private String userName;
private Boolean isAvailable;
public FBRowItem() {
this.imageId=null;
this.contactName=null;
this.userName=null;
this.isAvailable=false;
}
public FBRowItem(Bitmap imageId, String contactName, String userName, Boolean isAvailable) {
this.imageId = imageId;
this.contactName=contactName;
this.userName = userName;
this.isAvailable=isAvailable;
}
public Bitmap getImageId() {
return imageId;
}
public void setImageId(Bitmap imageId) {
this.imageId = imageId;
}
public String getContactName() {
return contactName;
}
public void setContactName(String contactName) {
this.contactName=contactName;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName=userName;
}
public Boolean getIsAvailable (){
return isAvailable;
}
public void setIsAvailable (Boolean isAvailable){
this.isAvailable=isAvailable;
}
#Override
public String toString() {
return contactName;
}
#Override
public int compareTo(Object arg0) {
FBRowItem f = (FBRowItem) arg0;
if((this.getIsAvailable()).equals(true)){
if((f.getIsAvailable()).equals(true))
return this.contactName.compareTo(f.contactName);
else return -1;
}
else{
if((f.getIsAvailable()).equals(true))
return +1;
else
return this.contactName.compareTo(f.contactName);
}
// return this.contactName.compareTo(f.contactName);
}
}
Here is the method that I call for sorting the contacts.
public static void receiveAllFBContacts(Context context){
rowItems = FB_FriendsActivity.friendsList(context);
Collections.sort(rowItems);
}
As you can see in the compareTo() method, if I use the last line that is actually only a comment at the moment, the Collections.sort(rowItems) works just fine, so I have all contacts sorted, but not with the separation of online and offline.
Problem: However, if I use the non-commented section as seen above, Collection.sort(rowItems) changes(!!) the statuses of all contacts to online for some reason. Tried reading some documentation, but couldn't get further. Any help is welcomed.
(rowItems is ArrayList "<"FBRowItem">" )
The code you posted can't cause the behavior you're seeing. I suggest looking elsewhere. Begin by debugging. Place a break point in your setIsAvailable method, see what's actually changing the status. (Its not your sorting.)