Realm findFirst() method returns null

半世苍凉 提交于 2020-01-13 08:32:34

问题


I searched and found FindFirst returns null question but no one answered it. As I'm thinking I am doing something wrong, let me explain my problem with more details.

I'm working on an app that asks the user to sign in first and then lets the user use the app.

My User class looks like this:

public class User extends RealmObject {

    @PrimaryKey
    @SerializedName("uid")
    String id;
    @SerializedName("ufname")
    String firstName;
    @SerializedName("ulname")
    String lastName;
    String avatar;
    int sessions;
    int invites;
    String nextSessionTime;
    String nextSessionTitle;
    @SerializedName("lastlogin")
    String lastLogin;
    String token;

    @Override
    public String toString() {
        return new GsonBuilder().create().toJson(this, User.class);
    }

    // other setters and getters
}

I store User's object in Realm db after successful login in SigninActivity class:

@Override
public void onSignInResponse(final GeneralResponse response) {

    if (response == null) {
        Timber.e("response is null");
        return;
    }
    Timber.d(response.toString());

    if (response.isSuccess()) {
        // Store user's info including Token
        realm.executeTransaction(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                realm.copyToRealmOrUpdate(response.getUser());
            }
        });

        // Goto main screen
        MainVideoActivity.startActivity(this);
        this.finish();

    } else {
        String errorMessage = response.getErrorMessages();
        super.displayMessage(errorMessage);
    }
}

Once the login is successful, app directs user to MainVideoActivity. I want to find user in realm by following code however I'm getting null.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main_video);

    // Create the Realm instance
    realm = Realm.getDefaultInstance();
    User user = realm.where(User.class).findFirst();
//        RealmResults<User> user = realm.where(User.class).findAll();
    Timber.d(user.toString());
}

user is null in both approaches.

However, I can see my none null user in db.

I'm using classpath "io.realm:realm-gradle-plugin:2.0.2"


回答1:


There are two things here:

  1. The null values in the debug window. That is a known limitation when using Realm with debugger. Since Realm generated a Proxy class to access values, inspecting the RealmObject's field in the debugger won't go through the proxy class. See more details here

  2. The fields with null values are not printed in the toString() method. Realm annotation processor will generate a toString() method if there is no toString() method defined in the RealmObject. I think the problem here is the a User.toString() ignores null values. Try to remove the toString() method in the User class.




回答2:


According Realm doc Realm you can try add isNotNull() in your query like this:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main_video);

    // Create the Realm instance
    realm = Realm.getDefaultInstance();
    User user = realm.where(User.class).isNotNull("id").findFirst(); //add in this line isNotNull()
    //RealmResults<User> user = realm.where(User.class).findAll();
    Timber.d(user.toString());
}

I have not tested yet, but it should work.




回答3:


Try replacing

    realm.executeTransaction(new Realm.Transaction() {
        @Override
        public void execute(Realm realm) {
            realm.copyToRealmOrUpdate(response.getUser());
        }
    });

    // Goto main screen
    MainVideoActivity.startActivity(this);
    this.finish();

with

    realm.executeTransactionAsync(new Realm.Transaction() {
        @Override
        public void execute(Realm realm) {
            realm.copyToRealmOrUpdate(response.getUser());
        }
    }, new Realm.Transaction.OnSuccess() {
        @Override
        public void onSuccess() {
            // Goto main screen
            MainVideoActivity.startActivity(this);
            finish();
        }
    });



回答4:


One way to workaround this is to create an unmanaged copy of the object.

Replace:

User user = realm.where(User.class).findFirst();

with

User managed_user = realm.where(User.class).findFirst();
  if(user!=null){
  User unmanaged_user = realm.copyFromRealm(managed_user)
}

Return unmanaged_user.



来源:https://stackoverflow.com/questions/40065366/realm-findfirst-method-returns-null

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!