101

I'm bloqued creating a Firebase Database.

I'm trying to model a class. A very simple class:

package com.glups.model;

import com.google.firebase.database.IgnoreExtraProperties;

@IgnoreExtraProperties
public class AlumnoFB {

    private String nombre;
    private String apellidos;
    private String telefono;
    private String email;
    private Boolean tieneWhatsapp;
    private Boolean tieneTelegram;
    private Boolean tieneHangouts;
    private Long formaPago;
    private Double ratioHora;
    private Double precioHora;
    private Double horasCompensadas;

    public AlumnoFB() {
        // Default constructor required for calls to DataSnapshot.getValue(User.class)
    }

    public AlumnoFB(String nombre,
                    String apellidos,
                    String telefono,
                    String email,
                    Boolean tieneWhatsapp,
                    Boolean tieneTelegram,
                    Boolean tieneHangouts,
                    Long formaPago,
                    Double ratioHora,
                    Double precioHora,
                    Double horasCompensadas) {
        this.nombre = nombre;
        this.apellidos = apellidos;
        this.telefono = telefono;
        this.email = email;
        this.tieneWhatsapp = tieneWhatsapp;
        this.tieneTelegram = tieneTelegram;
        this.tieneHangouts = tieneHangouts;
        this.formaPago = formaPago;
        this.ratioHora = ratioHora;
        this.precioHora = precioHora;
        this.horasCompensadas = horasCompensadas;
    }
}

that is almost like a sample class from Firebase.

Application user obtained from getUser() has been logged on Firebase.

When I call SetValue:

AlumnoFB alumno = new AlumnoFB("", "", "", "", false, false, false, ((Integer)FormaPago.INT_NO_PAGADO).longValue(), 0.0, 0.0, 0.0);
    mDatabase.child("AlumnoFB").child(ControlClasesFirebase.getUser().getUid()).setValue(alumno) ;

A fatal exception raises.

06-10 10:17:37.179 13841-13841/com.glups.controlclases E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.glups.controlclases, PID: 13841 com.google.firebase.database.DatabaseException: No properties to serialize found on class com.glups.model.AlumnoFB
at com.google.android.gms.internal.zzaix$zza.<init>(Unknown Source)
at com.google.android.gms.internal.zzaix.zzj(Unknown Source)
at com.google.android.gms.internal.zzaix.zzaw(Unknown Source)
at com.google.android.gms.internal.zzaix.zzav(Unknown Source)
at com.google.firebase.database.DatabaseReference.zza(Unknown Source)
at com.google.firebase.database.DatabaseReference.setValue(Unknown Source)
at com.glups.controlclases.MainActivity$4.onClick(MainActivity.java:305)
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:5258)
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)

I've checked types, and all are accepted. What's wrong?

Michael
  • 3,093
  • 7
  • 39
  • 83
EulerVen
  • 1,113
  • 2
  • 7
  • 5

12 Answers12

187

Firebase require your Pojo to have public variables or getter/setter.

Change variable declarations to public

public String nombre;
public String apellidos;
public String telefono;
public String email;
public Boolean tieneWhatsapp;
public Boolean tieneTelegram;
public Boolean tieneHangouts;
public Long formaPago;
public Double ratioHora;
public Double precioHora;
public Double horasCompensadas;
Shubhank
  • 21,721
  • 8
  • 65
  • 83
  • 1
    It seems to be logical. I have not yet defined getters/setter and I usually define my POJO variables private.It works. Thank you! – EulerVen Jun 10 '16 at 11:53
  • 15
    Even in doc examples I found private variables were used on the classes for the firebase database like 'FriendlyMessage'. I found they worked on my debug apk but not the release apk. Changing everything to public (and declaring the class outside the main application) fixed it. Always little pitfalls with Android. – Androidcoder Sep 24 '16 at 13:57
  • 1
    It makes sense to use them as public. Lol I should't have forgot that – Bharat May 30 '17 at 12:47
  • Having everything public wasn't enough, I also needed to have the Data class in its own file outside the main application as the second comment pointed out – masood elsad Jun 11 '17 at 11:10
  • Thanks ... This solved my problem . But I want to know something . At first the variable was declared as package private but this was not making any problem . But when I created the apk and installed on physical device I faced that problem . Why ? – Sudipta Basak Aug 04 '18 at 16:00
  • I am using Kotlin, where all variables are by default public. But even there I had to declare variables as public explicitly. Funny! – Mukesh Ghatiya Nov 28 '19 at 19:11
  • making your variables public is not good idea. create getters and setter of ALL your variables. – Imran Khan Apr 02 '21 at 10:53
120

If you are using proguard, some methods in the model could be stripped out depending on your configuration. As we know that there is no much optimization to POJO as it has only fields with getters and/or (optionally) setters, you can use the annotation "@Keep" so proguard will not delete any methods from this class.

Check this for more info: https://developer.android.com/studio/build/shrink-code.html

@Keep
public class Store {}
aselims
  • 1,843
  • 1
  • 17
  • 19
  • This finally resolved my 2 day ordeal and struggle of making the 'release' version of app working with firebase database. Debug was working fine but Release wasn't. It should have given me a hint to doubt Proguard but somehow I failed to do so. Thanks a lot for posting the answer! – Wahib Ul Haq Jul 22 '17 at 22:19
  • When I wrote this in proguard- rules.pro file, I got this error : `ProguardTokenType.CRLF, ProguardTokenType.FLAG_NAME , ProguardTokenType.LINE_CMT or ProguardTokenType.WS expected, got '@' ` – Shruti Dec 08 '17 at 06:28
  • To check if your proguard rules are working or not, check the output in build/outputs/mapping/release/seeds.txt and build/outputs/mapping/release/usage.txt more info here https://developer.android.com/studio/build/shrink-code.html – Ninja420 Mar 31 '19 at 08:54
34

In my case I forgot to add a proguard rule to keep the model classes:

-keep class com.google.firebase.example.fireeats.model.** { *; }

This is same as @aselims's answer, just proguard version.

I found it in the official firestore example:

https://github.com/firebase/quickstart-android/blob/master/firestore/app/proguard-rules.pro

Mahmudul Hasan Shohag
  • 2,203
  • 1
  • 22
  • 30
3

I have got this issue today and just resolve this providing getter/setter for private variables.

ex:

private String pid;

public String getPid() {
    return pid;
}

public void setPid(String pid) {
    this.pid = pid;
}

Now it's work perfectly without any error. Hope it will help newbies devs.

iamVishal16
  • 1,780
  • 18
  • 40
3

SOLUTION

In my case the issue was only in release/signed mode APK. So I fixed by doing these steps..

1- Added all model classes into proguaed rules like

-keep class com.YOUR_PACKAGE_NAME.modelClass.** { *; }

OR

@Keep
public class modelClass {}

2- Declared all variables of model class as private

3- Removed conflicting keys

Chill Pill :)

Ali Akram
  • 4,803
  • 3
  • 29
  • 38
  • This worked perfectly for my app that uses firebase. It used to only run well when installed from Android Studio but not when installed from a signed release (after proguarding) version of its apk – davejoem Jun 23 '21 at 23:38
2

Verify this:

buildTypes {
    release {
        minifyEnabled false
        ...
    }
    debug {
        minifyEnabled false
        ...
    }
}
Vadik Sirekanyan
  • 3,332
  • 1
  • 22
  • 29
0

Declare variables as public.

public String email
Marium Jawed
  • 391
  • 4
  • 9
0

In case anyone runs into this and none of the above solutions work, the variables declared also need to be of Object type and not raw types.

For example, you can use Integer's but you cannot use int's.

Same is true for boolean, float, double, etc. Basically, any unboxed type.

PGMacDesign
  • 6,092
  • 8
  • 41
  • 78
0

adding

@ServerTimeStamp
public Date date; 

helped me to resolve the issue

0

You can do either of the two things -

  1. Make your variables public OR
  2. Add getters and setters for all the variables
Abhinav Tripathi
  • 168
  • 1
  • 2
  • 12
0

To solve the issue as mentionned below you should declare the class as Serializable and for the code :

`data class Review(
    var rating:Float=0f,
    var userId:String="",
    var textR:String="",
    @ServerTimestamp var timestamp: Date? = null
 ):Serializable{
constructor( rating: Float,userId: String, text: String):this() {
    this.userId = userId
    this.rating = rating
    this.textR = text
}
}`
jadar_m
  • 39
  • 3
0

Try This Solution!

1- Implement Serializable interface

class model implements Serializable {}

2- Class Model with Private properties with Constructor and public setter and getter methods

public class Message implements Serializable {

@ServerTimestamp
private Date created;

private String content;
private String from;
private String to;

public Message(Date created, String content, String from, String to) {
    this.created = created;
    this.content = content;
    this.from = from;
    this.to = to;
}

public Date getCreated() {
    return created;
}

public void setCreated(Date created) {
    this.created = created;
}

public String getContent() {
    return content;
}

public void setContent(String content) {
    this.content = content;
}

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;
}

}

3- add this code in Proguard rules as said here

    # Add this global rule
-keepattributes Signature

# This rule will properly ProGuard all the model classes in
# the package com.yourcompany.models.
# Modify this rule to fit the structure of your app.
-keepclassmembers class com.yourcompany.models.** {
  *;
}
Islam Alshnawey
  • 692
  • 10
  • 15