【问题标题】:Firebase "User is missing a constructor with no arguments"Firebase“用户缺少没有参数的构造函数”
【发布时间】:2016-12-12 15:19:40
【问题描述】:

我正在尝试从 Firebase 中的 /User/ 树中检索我的用户详细信息。我有以下用户对象:

public class User {
    private String name;
    private String email;
    private FirebaseUser firebaseUser;
    private String lastOnline;
    private LatLng latLng;
    private ArrayList<SwapLocation> locations;

    public User(){ }

    public String getName(){
        if(firebaseUser.getDisplayName() != null && !firebaseUser.getDisplayName().equals(""))
            return firebaseUser.getDisplayName();

        if(name != null && !name.equals(""))
            return name;

        return "";
    }
    public void setName(String name){
        this.name = name;
    }

    public String getEmail(){
        if(firebaseUser.getEmail() != null && firebaseUser.getEmail().equals(""))
            return firebaseUser.getEmail();

        if(email != null && email.equals(""))
            return email;

        return "";
    }
    public void setEmail(String email){
        this.email = email;
    }

    public void setFirebaseUser(FirebaseUser firebaseUser){
        this.firebaseUser = firebaseUser;  
    }
    public FirebaseUser getFirebaseUser(){
        return firebaseUser;
    }

    public void setLastOnline(String lastOnline){
        this.lastOnline = lastOnline;
    }
    public String getLastOnline(){
        if(lastOnline != null)
            return lastOnline;

        return "";
    }

    public void setLatLong(LatLng latlng){
        this.latLng = latlng;
    }
    public LatLng getLatLong(){
        return this.latLng;
    }

    public ArrayList<SwapLocation> getLocations(){
        return locations;
    }
    public void setLocations(ArrayList<SwapLocation> locations){
        this.locations = locations;
    } 
}

我正在尝试从 Firebase 中检索此对象。该对象是在 dataSnapshot 中检索到的,尽管它在序列化到我的用户对象时存在问题。

这就是我从 Firebase 检索对象的方式:

DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child(users_group).child(user.getUid());
        ref.addListenerForSingleValueEvent(
            new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    User this_user = dataSnapshot.getValue(User.class); 
                }

                @Override
                public void onCancelled(DatabaseError databaseError) { }
            });

但是当尝试执行“用户 this_user = dataSnapshot.getValue(User.class)”时,我收到一条错误消息,提示“用户缺少没有参数的构造函数”

任何帮助都会很棒,谢谢

【问题讨论】:

  • 我无法解释为什么您会收到“缺少构造函数”错误。但我怀疑如果FirebaseUser 不是您定义的简单 POJO 而实际上是com.google.firebase.auth.FirebaseUser,Firebase 是否能够序列化/反序列化您的User 类。该类不是简单的 POJO,而且几乎可以肯定具有 Firebase 序列化程序无法处理的功能。
  • 快速猜测是您的User 类是在另一个类中定义的。如果是这种情况,请将其标记为静态:static public class User {。此外,正如 qbix 评论的那样,我怀疑 FirebaseUser 是否满足序列化的数据库要求(如果这样做会有点酷),所以你必须 @Exclude 那。
  • 啊该死的,这太糟糕了,因为我只想要一个用户对象。似乎我需要两个对象,一个 FirebaseUser 和一个 User 用于附加属性(因为用户可以在没有第 3 方身份验证的情况下登录,所以这些详细信息,例如姓名、电话等,需要存储在“用户”中的某个地方' 树)。或者替代方法是将 FirebaseUser 存储在我的 Users 对象中,并在调用 Firebase 时将其从 User 对象中剥离出来。嗯,你们认为最好的解决方案是什么?

标签: java android firebase firebase-realtime-database


【解决方案1】:

我在 kotlin 中使用 firebase 实时数据库遇到过这个问题,并通过 this solution

解决了这个问题

对于 Kotlin,如果您将以下数据类用于 firebase,

data class UserModel(
        var UserName: String,
        var UserType: Int
)

然后你会得到一个类似的错误

com.google.firebase.database.DatabaseException:UserModel 没有 定义一个无参数的构造函数。如果您使用 ProGuard,请确保 这些构造函数不会被剥离。

因此,您需要初始化它的值。

data class UserModel(
        var UserName: String = "",
        var UserType: Int = 0
)

【讨论】:

  • 太棒了!为我工作
【解决方案2】:

您一定会收到此错误,因为您的 User 类是子类。

解决方案:

要么将你的类标记为静态:

 public class SomeParentClass{ 

        public static class User {
            ....
        }
    }

或在单独的文件中创建它。

【讨论】:

  • 这为我解决了这个问题。错误消息很棘手,因为无论您的构造函数是否包含为数据库创建的任何类都没有参数的构造函数,如果您像我最初所做的那样在主要活动中通用定义该类,则错误消息很棘手。该消息暗示了类定义的问题,而不是定义位置和方式的真正问题。
【解决方案3】:

User has no arguments 错误意味着即使你确实需要一个空的构造函数:

public User(){ }

您还需要另一个构造函数,其中的变量是构造函数内部 Firebase 对象中的子对象。例如:

 public User(
      String name,
      String email,
      FirebaseUser firebaseUser,
      String lastOnline,
      LatLng latLng,
      ArrayList<SwapLocation> locations
 ){
      this.name = name;
      this.email = email;
      this.firebaseUser = firebaseUser;
      this.lastOnline = lastOnline;
      this.latLong = latLong;
      this.locations = locations;
 }

还要注意SwapLocation等构造函数内部的类,如果没有自动解析,需要用同样的方式修改。

另一方面,在 Kotlin 中,您不应使用空值进行实例化,而应使用 null 进行实例化,并在顶部添加 @IgnoreExtraProperties@Keep 以仅当属性存在于数据中时才加载它们。例如:

@Keep
@IgnoreExtraProperties
open class User(
     var name : String? = null,
     var email : String? = null,
     var firebaseUser : FirebaseUser? = null,
     var lastOnline : String? = null,
     var latLng : LatLng? = null,
     var locations : ArrayList<SwapLocation>? = null
)

希望对你有帮助!

【讨论】:

    【解决方案4】:

    在 kotlin 中需要初始化数据类构造器变量来诊断这个错误。

    data class Images(val imageOne:String="",
                      val imageTwo:String="",
                      val imageThree:String=""
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-21
      • 1970-01-01
      • 1970-01-01
      • 2021-07-06
      • 1970-01-01
      • 2016-03-08
      • 2018-05-13
      相关资源
      最近更新 更多