在 Android Studio 中不使用 Instant 运行 时出现 Firebase DatabaseException

Firebase DatabaseException when not using Instant Run in Android Studio

当我使用 Instant 运行 时,我的应用程序工作正常,但是,当我尝试调试它或不使用 instant 运行 时,它在 Logcat 中给了我这个:

04-24 22:16:15.864 22359-22359/com.clairvoyance.bookmarket E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.clairvoyance.bookmarket, PID: 22359
com.google.firebase.database.DatabaseException: No properties to serialize found on class com.clairvoyance.bookmarket.User
    at com.google.android.gms.internal.zzeph.<init>(Unknown Source)
    at com.google.android.gms.internal.zzepg.zzf(Unknown Source)
    at com.google.android.gms.internal.zzepg.zzb(Unknown Source)
    at com.google.android.gms.internal.zzepg.zza(Unknown Source)
    at com.google.firebase.database.DataSnapshot.getValue(Unknown Source)
    at com.clairvoyance.bookmarket.ActMainActivity.onDataChange(ActMainActivity.java:55)
    at com.google.firebase.database.zzp.onDataChange(Unknown Source)
    at com.google.android.gms.internal.zzejp.zza(Unknown Source)
    at com.google.android.gms.internal.zzelk.zzcal(Unknown Source)
    at com.google.android.gms.internal.zzelq.run(Unknown Source)
    at android.os.Handler.handleCallback(Handler.java:751)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:163)
    at android.app.ActivityThread.main(ActivityThread.java:6228)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

我试过破坏我的亲卫规则。我不确定这是否正确:

   # Uncomment this to preserve the line number information for
   # debugging stack traces.
   -keepattributes SourceFile,LineNumberTable

   # If you keep the line number information, uncomment this to
   # hide the original source file name.
   -renamesourcefileattribute SourceFile

   -keep class com.firebase.** { *; }
   -keep class org.apache.** { *; }
   -keepnames class com.fasterxml.jackson.** { *; }
   -keepnames class javax.servlet.** { *; }
   -keepnames class org.ietf.jgss.** { *; }
   -dontwarn org.w3c.dom.**
   -dontwarn org.joda.time.**
   -dontwarn org.shaded.apache.**
   -dontwarn org.ietf.jgss.**

   # Add this global rule
   -keepattributes Signature

   -keepclassmembers class com.clairvoyance.bookmarket.** {
     *;
   }

我的调试器专注于这一行:

   mainUser = dataSnapshot.getValue(User.class);

所以我花了很多时间检查我的用户 class 看看那里是否有任何问题。这是我的 ActMainActivity 和 User Class:

中的函数

主要活动:

public class ActMainActivity extends AppCompatActivity implements 
BookListFragment.OnListFragmentInteractionListener {

    User mainUser;
    ViewPager actViewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setToolbar();
        actViewPager = findViewById(R.id.main_pager);
        setMainUser();
    }

    private void setToolbar() {
        Toolbar myToolbar = findViewById(R.id.main_toolbar);
        myToolbar.setTitleTextColor(Color.parseColor("#FFFFFF"));
        myToolbar.setTitle(R.string.app_name);
        setSupportActionBar(myToolbar);
        // Get a support ActionBar corresponding to this toolbar
    }

    private void setMainUser() {
        String uid = WebServiceHandler.getUID();
        if (uid == null) {
            illegalAccess();
            return;
        }

        DatabaseReference userRef = WebServiceHandler.getRootRef().child("users").child(uid);
        userRef.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                if (!dataSnapshot.exists()) {
                    illegalAccess();
                } else {

                    Log.d("MainActivityCycle", "mainUserSet");
                    mainUser = dataSnapshot.getValue(User.class); // Line 55 Where logcat points to
                    if (mainUser != null) {
                        // Set up the GUI now that the mainUser is set (we'll need its data)
                        actViewPager.setAdapter(new MainPagerAdapter(getSupportFragmentManager(), mainUser));
                        actViewPager.setCurrentItem(1);
                    }
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
    }
}

用户Class:

package com.clairvoyance.bookmarket;

import com.google.firebase.database.IgnoreExtraProperties;
import java.io.Serializable;
import java.util.HashMap;

/**
 * Created by Sathya on 12/21/2017.
 *
 */
// Todo: Implement Parcelable (for argument passing in bundles in fragments)
@IgnoreExtraProperties
class User implements Serializable {
    private String name;
    private String email;
    private HashMap<String, Object> bookIDs = new HashMap<>();

    // Key is bookID!!! - Value is requestID!!!!
    private HashMap<String, String> myRequestIDs = new HashMap<>();
    private boolean isEmailVerified = false;
    private String registrationToken;

    public User(){ }

    User(String email){
        this.email = email;
    }

    void setName(String name) {
        this.name = name;
    }
    void setEmailVerified(boolean emailVerified) { isEmailVerified = emailVerified; }
    void addBook(Book book){
        bookIDs.put(book.getBookID(), true);
    }
    void addMyRequest(Request request){
        myRequestIDs.put(request.getBookID(), request.getRequestID());
    }
    void setRegistrationToken(String registrationToken) {
        this.registrationToken = registrationToken;
    }

    String getName() {
        return name;
    }
    String getEmail() {
        return email;
    }
    boolean isEmailVerified() {
        return isEmailVerified;
    }
    HashMap<String, Object> getBookIDs() {
        return bookIDs;
    }
    HashMap<String, String> getMyRequestIDs() {
        return myRequestIDs;
    }
    String getRegistrationToken() {
        return registrationToken;
    }
}

提前致谢。

您需要将 user class 的变量和方法变为 public 变量。

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