无法将Firebase解析的数据存储到Realm数据库中

时间:2018-06-29 03:45:32

标签: android firebase firebase-realtime-database realm

大家好,我是用Firebase解析A Books信息的,而我是在尝试将数据存储在Realm数据库中的,以便用户可以脱机访问数据 但是我每次都会有例外
我试图在stackoverflow和google中搜索此问题,但每次遇到此异常都没有得到很好的答案,因此我希望大家对这个问题有所帮助,在此先感谢您的宝贵时间< / p>

    E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.w4ma.soft.tamenly, PID: 28122
                  java.lang.NullPointerException: Attempt to invoke virtual method 'int io.realm.RealmResults.size()' on a null object reference
                      at com.w4ma.soft.tamenly.CategoryActivities.Models.BooksModel.BooksAdapter.getItemCount(BooksAdapter.java:213)
                      at android.support.v7.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:3722)
                      at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3527)
                      at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:4082)
                      at android.view.View.layout(View.java:17663)
                      at android.view.ViewGroup.layout(ViewGroup.java:5577)
                      at com.baoyz.widget.PullRefreshLayout.onLayout(PullRefreshLayout.java:512)
                      at android.view.View.layout(View.java:17663)
                      at android.view.ViewGroup.layout(ViewGroup.java:5577)
                      at android.support.constraint.ConstraintLayout.onLayout(ConstraintLayout.java:1858)
                      at android.view.View.layout(View.java:17663)
                      at android.view.ViewGroup.layout(ViewGroup.java:5577)
                      at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
                      at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
                      at android.view.View.layout(View.java:17663)
                      at android.view.ViewGroup.layout(ViewGroup.java:5577)
                      at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741)
                      at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
                      at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
                      at android.view.View.layout(View.java:17663)
                      at android.view.ViewGroup.layout(ViewGroup.java:5577)
                      at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
                      at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
                      at android.view.View.layout(View.java:17663)
                      at android.view.ViewGroup.layout(ViewGroup.java:5577)
                      at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741)
                      at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
                      at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
                      at android.view.View.layout(View.java:17663)
                      at android.view.ViewGroup.layout(ViewGroup.java:5577)
                      at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
                      at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
                      at com.android.internal.policy.DecorView.onLayout(DecorView.java:730)
                      at android.view.View.layout(View.java:17663)
                      at android.view.ViewGroup.layout(ViewGroup.java:5577)
                      at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2383)
                      at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2105)
                      at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1291)
                      at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6396)
                      at android.view.Choreographer$CallbackRecord.run(Choreographer.java:876)
                      at android.view.Choreographer.doCallbacks(Choreographer.java:688)
                      at android.view.Choreographer.doFrame(Choreographer.java:623)
                      at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:862)
                      at android.os.Handler.handleCallback(Handler.java:754)
                      at android.os.Handler.dispatchMessage(Handler.java:95)
                      at android.os.Looper.loop(Looper.java:163)
                      at android.app.ActivityThread.main(ActivityThread.java:6221)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
I/DynamiteModule: Considering local module com.google.android.gms.flags:2 and remote module com.google.android.gms.flags:3
                  Selected remote version of com.google.android.gms.flags, version >= 3
V/FA: Not logging ad unit exposure. No active activity
      Not logging ad exposure. No active activity
W/DynamiteModule: Local module descriptor class for com.google.firebase.auth not found.
W/BiChannelGoogleApi: [FirebaseAuth: ] getGoogleApiForMethod() returned Gms: com.google.firebase.auth.api.internal.zzal@8dcd42b
W/BiChannelGoogleApi: [FirebaseAuth: ] getGoogleApiForMethod() returned Gms: com.google.firebase.auth.api.internal.zzal@8dcd42b
D/FA: Logging event (FE): screen_view(_vs), Bundle[{firebase_event_origin(_o)=auto, firebase_previous_class(_pc)=MainActivity, firebase_previous_id(_pi)=-8357801964819412298, firebase_screen_class(_sc)=BookActivity, firebase_screen_id(_si)=-8357801964819412282}]
W/DynamiteModule: Local module descriptor class for com.google.firebase.auth not found.
I/FirebaseAuth: [FirebaseAuth:] Loading module via FirebaseOptions.
                [FirebaseAuth:] Preparing to create service connection to gms implementation
V/FA: Activity resumed, time: 275219039
E/CrashlyticsCore: Failed to execute task.
                   java.util.concurrent.TimeoutException
                       at java.util.concurrent.FutureTask.get(FutureTask.java:177)
                       at com.crashlytics.android.core.CrashlyticsBackgroundWorker.submitAndWait(CrashlyticsBackgroundWorker.java:41)
                       at com.crashlytics.android.core.CrashlyticsController.handleUncaughtException(CrashlyticsController.java:320)
                       at com.crashlytics.android.core.CrashlyticsController$6.onUncaughtException(CrashlyticsController.java:300)
                       at com.crashlytics.android.core.CrashlyticsUncaughtExceptionHandler.uncaughtException(CrashlyticsUncaughtExceptionHandler.java:42)
                       at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1068)
                       at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1063)
                       at java.lang.Thread.dispatchUncaughtException(Thread.java:1979)
  

BookList.class

    public class BookList extends RealmObject {

//    @PrimaryKey
//    private String realmID;
    private String post_id;
    private String post_title;
    private String post_real_price;
    private String currency;
    private String post_description;
    private String post_image;
    private String post_datetime;
    private String category;

//    public String getRealmID() {
//        return realmID;
//    }
//
//    public void setRealmID(String realmID) {
//        this.realmID = realmID;
//    }

    public String getPost_id() {
        return post_id;
    }

    public void setPost_id(String post_id) {
        this.post_id = post_id;
    }

    public String getPost_title() {
        return post_title;
    }

    public void setPost_title(String post_title) {
        this.post_title = post_title;
    }

    public String getPost_real_price() {
        return post_real_price;
    }

    public void setPost_real_price(String post_real_price) {
        this.post_real_price = post_real_price;
    }

    public String getCurrency() {
        return currency;
    }

    public void setCurrency(String currency) {
        this.currency = currency;
    }

    public String getPost_description() {
        return post_description;
    }

    public void setPost_description(String post_description) {
        this.post_description = post_description;
    }

    public String getPost_image() {
        return post_image;
    }

    public void setPost_image(String post_image) {
        this.post_image = post_image;
    }

    public String getPost_datetime() {
        return post_datetime;
    }

    public void setPost_datetime(String post_datetime) {
        this.post_datetime = post_datetime;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public String getUser_name() {
        return user_name;
    }

    public void setUser_name(String user_name) {
        this.user_name = user_name;
    }

    public String getUser_pp() {
        return user_pp;
    }

    public void setUser_pp(String user_pp) {
        this.user_pp = user_pp;
    }

    public String getUser_ID() {
        return user_ID;
    }

    public void setUser_ID(String user_ID) {
        this.user_ID = user_ID;
    }

    private String user_name;
    private String user_pp;
    private String user_ID;

    public BookList( String post_id, String post_title, String post_real_price, String currency, String post_description, String post_image, String post_datetime, String category, String user_name, String user_pp, String user_ID) {
        //this.realmID = realmID;
        this.post_id = post_id;
        this.post_title = post_title;
        this.post_real_price = post_real_price;
        this.currency = currency;
        this.post_description = post_description;
        this.post_image = post_image;
        this.post_datetime = post_datetime;
        this.category = category;
        this.user_name = user_name;
        this.user_pp = user_pp;
        this.user_ID = user_ID;
    }




    public BookList() {
    }  //Constructer

}
  

BooksAdapter.class

 public class BooksAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {


    public BooksAdapter(RealmResults<BookList> listy, Context mContext) {
        this.listy = listy;
        this.mContext = mContext;
    }

    RealmResults<BookList> listy;
    TinyDB tinyDB;
    Context mContext;



    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {


        if (viewType == 12 ){
            return new AdsViewHolder(LayoutInflater.from(mContext.getApplicationContext()).inflate(R.layout.bigadbanner,parent,false));
        }else {
            return new BooksViewHolder(LayoutInflater.from(mContext.getApplicationContext()).inflate(R.layout.row_item,parent,false));
        }
    }

    @Override
    public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position) {
        tinyDB = new TinyDB(mContext);
        final String country = tinyDB.getString("country");
        int viewType = getItemViewType(position);

        if (viewType == 12) {

            AdsViewHolder adsHolder = (AdsViewHolder) holder;
            AdRequest adRequest = new AdRequest.Builder().build();
            adsHolder.BigBannerAdView.loadAd(adRequest);
            adsHolder.BigBannerAdView.setAdListener(new AdListener() {
                @Override
                public void onAdLoaded() {
                    // Code to be executed when an ad finishes loading.
                }

                @Override
                public void onAdFailedToLoad(int errorCode) {
                    // Code to be executed when an ad request fails.
                    Toasty.info(mContext, mContext.getString(R.string.disable_adblock), Toast.LENGTH_LONG).show();
                }

                @Override
                public void onAdOpened() {
                    // Code to be executed when an ad opens an overlay that
                    // covers the screen.
                }

                @Override
                public void onAdLeftApplication() {
                    // Code to be executed when the user has left the app.
                }

                @Override
                public void onAdClosed() {
                    // Code to be executed when when the user is about to return
                    // to the app after tapping on an ad.
                }
            });

        } else {

            final BooksViewHolder BooksHolder = (BooksViewHolder) holder;
           final BookList list = listy.get(position);

            BooksHolder.PostTitle.setText(list.getPost_title());
            BooksHolder.PostDate.setText(list.getPost_datetime());

            Glide.with(mContext)
                    .load(list.getPost_image())
                    .into(BooksHolder.imgPostCover);


            BooksHolder.UserProfileName.setText(list.getUser_name());

            Picasso.get()
                    .load(list.getUser_pp())
                    .placeholder(R.drawable.user)
                    .into(BooksHolder.TheUserProfilePic);

            BooksHolder.linearLayout.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    // When Clicking On  the Post the app will send a UserID to the Server with generated Key

                    FirebaseUser mAuth = FirebaseAuth.getInstance().getCurrentUser();

                    String postID = list.getPost_id();

                    Intent intent = new Intent(mContext, ShowThePost.class);

                    intent.putExtra("post_ID", list.getPost_id());
                    intent.putExtra("post_Title", list.getPost_title());
                    intent.putExtra("post_Desc", list.getPost_description());
                    intent.putExtra("post_Image", list.getPost_image());
                    intent.putExtra("post_DateTime", list.getPost_datetime());
                    intent.putExtra("post_Price", list.getPost_real_price());
                    intent.putExtra("post_Currency", list.getCurrency());
                    intent.putExtra("post_UserName", list.getUser_name());
                    intent.putExtra("post_UserProfilePicture", list.getUser_pp());
                    intent.putExtra("category", list.getCategory());
                    intent.putExtra("userID", list.getUser_ID());

                    mContext.startActivity(intent);

                    String userName = mAuth.getDisplayName();
                    DatabaseReference dbViewCount = FirebaseDatabase.getInstance().getReference(country);
                    dbViewCount.child("Posts").child(postID).child("Views").push().setValue(userName);
                }
            });


//_______________________________________________________________________________________________

            //Get Comments Count

            final String category = list.getCategory();
            final String postID = list.getPost_id();

            DatabaseReference dbCommentsCount = FirebaseDatabase.getInstance().getReference(country).child("Posts");
            dbCommentsCount.child(category).child(postID).child("Comments").addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    long CommentsCount = dataSnapshot.getChildrenCount();
                    BooksHolder.txtCountComments.setText(String.valueOf(CommentsCount));
                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {
                    Toasty.error(mContext, databaseError.getMessage(), Toast.LENGTH_LONG).show();
                }
            });

            //=========================================================================================
            //get Views Count

            DatabaseReference dbViewsCount = FirebaseDatabase.getInstance().getReference(country).child("Posts");
            dbViewsCount.child(category).child(postID).child("Views").addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    long ViewsCount = dataSnapshot.getChildrenCount();
                    BooksHolder.txtCountViews.setText(String.valueOf(ViewsCount));
                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {
                    Toasty.error(mContext, databaseError.getMessage(), Toast.LENGTH_LONG).show();
                }
            });

//------------------------------------------------------------------------------------------------------
        }
    }


    @Override
    public int getItemViewType(int position) {
        if (position == 3) {

            return 12;
        } else {

            return super.getItemViewType(position);
        }
    }

    @Override
    public int getItemCount() {
        return listy.size();
    }

    public class BooksViewHolder extends RecyclerView.ViewHolder {

          @BindView(R.id.TheuserProfilePicture)
        CircularImageView TheUserProfilePic;
         @BindView(R.id.userName)
        TextView UserProfileName;
         @BindView(R.id.imgPostShow)
         RoundedImageView imgPostCover;
          @BindView(R.id.postTitle)
        TextView PostTitle;
         @BindView(R.id.txt_Post_Date)
        TextView PostDate;
         @BindView(R.id.GotoPostItem)
         MaterialRippleLayout linearLayout;

         @BindView(R.id.txtCountViews)
        TextView txtCountViews;
       @BindView(R.id.txtCountComments)
        TextView txtCountComments;


        public BooksViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }
    }

    public class AdsViewHolder extends RecyclerView.ViewHolder {

        @BindView(R.id.BigBannerAdView)
        AdView BigBannerAdView;

        public AdsViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);

        }
    }
}
  

BooksActivity.class,这是应该在其中查看数据的活动   Recyclerview

    public class BookActivity extends AppCompatActivity {


    @Override
    protected void onDestroy() {
        super.onDestroy();
        realm.close();
    }
    @Override
    protected void onPause() {
        super.onPause();
    }

    private static final String TAG = "TAG";


    @BindView(R.id.Postgo) FloatingActionButton floatingActionButton;



    @BindView(R.id.main_swipe)
    PullRefreshLayout waveSwipeRefreshLayout;
    @BindView(R.id.recyclerBooks) RecyclerView rcBooks;
    BooksAdapter adapter;
    DatabaseReference dbref;
    RealmResults<BookList> list;
    TinyDB tinyDB;
    Realm realm;


    @Deprecated
    ProgressDialog dialog;

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        CustomIntent.customType(this,"right-to-left");
        finish();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_books);
        ButterKnife.bind(this);

        Realm.getDefaultInstance();

        tinyDB = new TinyDB(this);
        Refreshing();


        floatingActionButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(BookActivity.this,CreatePostActivity.class);
                intent.putExtra("name","Books");
                startActivity(intent);
            }
        });


        final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        rcBooks.setLayoutManager(linearLayoutManager);
        rcBooks.setHasFixedSize(true);
        rcBooks.smoothScrollToPosition(0);
        rcBooks.setItemAnimator(new DefaultItemAnimator());


        try {
            retriveData();
            list = realm.where(BookList.class).findAllAsync().sort("realmID", Sort.DESCENDING);
        } catch (Exception e) {
            Crashlytics.logException(e);

          Toasty.error(BookActivity.this,getString(R.string.exception_code) + e.getMessage()  ,Toast.LENGTH_LONG).show();
            Log.d(TAG, "onRetriveData: " + e.getMessage());
        }
    }

    public void  retriveData() {

        String country = tinyDB.getString("country");

        if (country != null || !country.isEmpty()) {

            dbref = FirebaseDatabase.getInstance().getReference(country).child("Posts");
            dbref.keepSynced(true);
            dbref.child("Books").addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {

                    for (DataSnapshot dtSnapshot : dataSnapshot.getChildren()) {

                        if (!dataSnapshot.hasChildren()) {
                            Toasty.info(BookActivity.this, getString(R.string.no_more_posts), Toast.LENGTH_SHORT).show();

                        } else {
                            BookList modelList = dtSnapshot.getValue(BookList.class);

                          //  modelList.setRealmID(String.valueOf(NextKey()));
                            realm.beginTransaction();
                            realm.copyToRealmOrUpdate(modelList);
                            realm.commitTransaction();
                            realm.close();

                            Log.d(TAG, "onDataChange: " + modelList);
                            adapter.notifyDataSetChanged();

                        }
                    }

                }

                @Override
                public void onCancelled(DatabaseError databaseError) {

                    Toast.makeText(BookActivity.this, getString(R.string.something_went_wrong) + databaseError.getMessage(), Toast.LENGTH_SHORT).show();
                }
            });


            adapter = new BooksAdapter(list,BookActivity.this);
            final SkeletonScreen skeletonScreen = Skeleton.bind(rcBooks)
                    .adapter(adapter)
                    .shimmer(true)
                    .angle(20)
                    .frozen(false)
                    .duration(1000)
                    .count(10)
                    .load(R.layout.comment_row)
                    .show(); //default count is 10





            skeletonScreen.hide();


            waveSwipeRefreshLayout.setRefreshing(false);
        }else {

            Toasty.error(BookActivity.this,getString(R.string.error_code_b16) ,Toast.LENGTH_LONG).show();


        }

    }

    public void Refreshing(){


        waveSwipeRefreshLayout.setOnRefreshListener(new PullRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
             retriveData();

            }
        });

    }

public int NextKey(){

    try {
        return realm.where(BookList.class).max("realmID").intValue() + 1;
    } catch (ArrayIndexOutOfBoundsException | NullPointerException e ) {
        return 0;
    }
}
}

1 个答案:

答案 0 :(得分:0)

在您的retriveData()方法中,您正在创建BooksAdapter的新实例,如下所示:

adapter = new BooksAdapter(list,BookActivity.this);

您正在将list的值传递给此新实例。问题在于,当调用retriveData()时,尚未分配list,即null。您的retriveData()方法在传递之前没有分配list,因此它传递的是null值。您仅在呼叫list后分配retriveData()

retriveData();
list = realm.where(BookList.class).findAllAsync().sort("realmID", Sort.DESCENDING);

所以您在这里得到NullPointerException

public int getItemCount() {
    return listy.size();
}

尝试在null对象引用上调用方法。

一种解决方案是在实例化list之前分配BooksAdapter

为帮助您在代码中发现这些类型的问题,请考虑对预期不会成为@NonNull的变量使用null批注:

@NonNull
RealmResults<BookList> listy;

这将为您指出null值的问题,否则您可能会忽略它们。了解有关注释here的更多信息。

您的代码的另一个问题是:

Realm.getDefaultInstance();

此处,返回的Realm实例未分配任何内容。您显然打算将其分配给realm。因此,realm也是null。更改为:

realm = Realm.getDefaultInstance();