Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NullPointerException when running from Google Play but not from Android Studio

I'm having a big issue, I do not know what's happening, I've uploaded an app to Play Store because when I was running it on an Emulator or even on my real device it wasn't crashing, but now when I download it from Google Play it says :

java.lang.NullPointerException: 
  at com..onBindViewHolder (ChooseCard.java)
  or                     .onCreateViewHolder (ChooseCard.java)
  at com..onBindViewHolder (ChooseCard.java)
  or                     .onCreateViewHolder (ChooseCard.java)
  at com.firebase.ui.database.FirebaseRecyclerAdapter.getItemCount (FirebaseRecyclerAdapter.java)
  or                     .onBindViewHolder (FirebaseRecyclerAdapter.java)
  or                     .onChildChanged (FirebaseRecyclerAdapter.java)
  or                     .onError (FirebaseRecyclerAdapter.java)
  at com.yarolegovich.discretescrollview.InfiniteScrollAdapter.access$100 (InfiniteScrollAdapter.java)
  or                     .getItemCount (InfiniteScrollAdapter.java)
  or                     .getItemViewType (InfiniteScrollAdapter.java)
  or                     .onAttachedToRecyclerView (InfiniteScrollAdapter.java)
  or                     .onBindViewHolder (InfiniteScrollAdapter.java)
  or                     .onCreateViewHolder (InfiniteScrollAdapter.java)
  or                     .wrap (InfiniteScrollAdapter.java)

It's been days with this issue and I can't find it out, could you give me a hand please?

There's my build.gradle implementations

implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
implementation 'com.android.support:design:27.1.1'
implementation 'com.intuit.sdp:sdp-android:1.0.4'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
implementation 'com.android.support:cardview-v7:27.1.1'
implementation 'com.google.firebase:firebase-core:15.0.0'
implementation 'com.google.firebase:firebase-auth:15.0.0'
implementation 'com.google.android.gms:play-services-auth:15.0.0'
implementation 'com.google.firebase:firebase-database:15.0.0'
implementation 'com.anjlab.android.iab.v3:library:1.0.44'
implementation 'com.firebaseui:firebase-ui-database:3.3.1'
implementation 'com.onesignal:OneSignal:3.7.1'
implementation 'com.yarolegovich:discrete-scrollview:1.3.2'
implementation 'com.pranavpandey.android:dynamic-toasts:0.9.0'
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.11'
implementation 'com.google.android.gms:play-services-analytics:15.0.0'
.....
 dependencies {
        classpath 'com.android.tools.build:gradle:3.1.2'
        classpath 'com.google.gms:google-services:3.2.1'

Edit

I've updated my app on Google Play and nothing happens, still crashing on the same Activity, I do now know what to do to debug this, the problem is when I download the app from Google Play, on Emulator (even in a new emulator device is not crashing) and on my real device.

As @Marcos Vascondelos said, I did Build > Genereate Signed APK > get the app-release.apk install it on my device and the problem is that I can not login it is going to this method :

 @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
        if (requestCode == RC_SIGN_IN) {
            Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
            try {
                // Google Sign In was successful, authenticate with Firebase
                GoogleSignInAccount account = task.getResult(ApiException.class);
                firebaseAuthWithGoogle(account);
            } catch (ApiException e) {
                // Google Sign In failed, update UI appropriately
                Log.w(TAG, "Google sign in failed", e.getCause());
                Toast with e.getCause is null
            }
        }
    }

If you want to see how do I login to not put more code on this question I put on this GitHubGist

I've read that it could be problems with SHA-1, but I don't know why on emulator is ok, device is ok, Google play is ok, but if I install the .apk directly it says null.

LAST EDIT

I see the problem is not on the Firebase call, is on the populate the list, I mean the products are caught correctly, but when I try to put into the list is where it crashes

My FirebaseRecyclerOptions adapter looks like

 final FirebaseRecyclerOptions< CardPOJO > options =
                    new FirebaseRecyclerOptions.Builder< CardPOJO >()
                            .setQuery(products_ref, CardPOJO.class)
                            .build();



            adapter = new   FirebaseRecyclerAdapter< CardPOJO, CardHolder>(options) {
                @Override
                public CardHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                    //inflate the single recycler view layout(item)
                    View view = LayoutInflater.from(parent.getContext())
                            .inflate(R.layout.card_product, parent, false);
                    final CardHolder cardViewHolder = new CardHolder(view);
                    return cardViewHolder;
                }



                @Override
                public void onDataChanged() {
                    super.onDataChanged();
                    if(progressDialog!=null)progressDialog.dismiss();initViews();
                }


                @Override
                protected void onBindViewHolder(final CardHolder holder, int position, final CardPOJO model) {
                    holder.itemView.setSelected(0== position); ////where you are in the list
                    holder.getLayoutPosition();
                    switch (model.getState()){
                        case "free":
                            holder.card_image.setImageResource();
                            break;
                        case "not_free":
                            if(userOwnsProduct(model.getProduct_id())){
                                holder.card_image.setImageResource();
                            }
                            else{
                                holder.card_image.setImageResource();
                            }

                            break;
                        default:
                            break;
                    }
                    holder.view.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            if(model.getState().equals("free")){
                                //normal stuff1

                            }
                            else{
                                if (!readyToPurchase) {
                                    DynamicToast.makeError(mContext,"Problems with Google Play",Toast.LENGTH_SHORT).show();
                                    return;
                                }
                                root_ref.child("PurchasedProducts").child(currentUser).addValueEventListener(new ValueEventListener() {
                                    @Override
                                    public void onDataChange(DataSnapshot dataSnapshot) {
                                        if(dataSnapshot.hasChild(model.getProduct_id())){
                                            //Normal stuff
                                        }
                                        else{
                                            bp.purchase((Activity) mContext,model.getProduct_id());
                                        }
                                    }

                                    @Override
                                    public void onCancelled(DatabaseError databaseError) {

                                    }
                                });

                            }

                        }
                    });


                }

            };
            adapter.startListening();



            infiniteAdapter = InfiniteScrollAdapter.wrap(adapter);
            itemPicker.setAdapter(infiniteAdapter);
            //.setItemTransitionTimeMillis(DiscreteScrollViewOptions.getTransitionTime());
            itemPicker.setItemTransformer(new ScaleTransformer.Builder()
                    .setMinScale(0.5f)
                    .build());
like image 642
Skizo-ozᴉʞS Avatar asked Apr 25 '18 12:04

Skizo-ozᴉʞS


4 Answers

The problem was when using Proguard, I did not use @Keep on my pojo classes, so when trying to serialize the class with firebase database wasn't finding the attributes because they were obfuscates.

like image 61
Skizo-ozᴉʞS Avatar answered Oct 24 '22 07:10

Skizo-ozᴉʞS


Remember , always check if component is null or not . Than execute your code . example :

if ("your_component" != null){
//your code
}
like image 39
Stavro Xhardha Avatar answered Oct 24 '22 09:10

Stavro Xhardha


You seem to have tried almost everything I could come up with. It can be an issue with SHA-1. Try these :

  • Firstly, check if the child you are accessing actually exists.(ie not null)
  • Try checking if you actually have access for adding products. Also, check Firebase rules.
  • Try adding product with different kinds of users (if your app contains different types of users).
like image 24
Aman B. Avatar answered Oct 24 '22 09:10

Aman B.


OK here it goes! I saw the code there is an anomaly possibly being ignored like in high end apis.In simple words for api 23 and >23 like getting the context using ViewGroup Parent in the viewHolder area! is no problem but on small api devices I think this will be an issue!

so try this hope this will help!

Maybe I am seeing it from this perspective hope this helps

public CardHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                                //inflate the single recycler view layout(item)
                           //  !!!!!!!!!!!!! **the issue is here**! !!!!!!!!!!!!!!!
                                View view = LayoutInflater.from(parent.getContext())
                                        .inflate(R.layout.card_product, parent, false);
                                final CardHolder cardViewHolder = new CardHolder(view);
                                return cardViewHolder;
                            }

You are not having your layout inflated properly! Getting Context like this is maybe the cause of the NULL POINTER EXCEPTION on that class! There is simple way to do it ! like get the Context of the activity by taking it using adapter's Constructor while being instantiated.

here is example!

public class yourActivity extends AppCompatActivity{
   YourAdapter mAdapter; 
/// lets say you are setting it up in android ONCREATE Method
@override
public void OnCreate(....){
...........

mAdapter(data,design,YourActivity.this);
 //here this will be the context going in your adapter simple

}

}

In your adapter's constructor you can have it stored in a global variable like this maybe

public class YourAdapter extends RECYCLERView.Adapter......{
Context mContext;
public YourAdapter(Data data, int design,Context mContext)
this.mContext = mContext;
}
//and now you can access without any stress about context null exception 
   public CardHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                            //inflate the single recycler view layout(item)
                            View view = LayoutInflater.from(mContext)
                                    .inflate(R.layout.card_product, parent, false);
                            final CardHolder cardViewHolder = new CardHolder(view);
                            return cardViewHolder;
                        }

FIRST ANOMALY is exposed and resolved by the code above. the second one that I hoped upon is like this

You are trying to use RecyclerView but not Providing it with the SubClass for holding the Views!

whenEver we make adapter for a recycler view were are bound to have the Subclass for ViewHolder to do simply the Recycling for us. the major work of that subclass is to hold the Views and findThem using their ids

for generic example try this link I found ! credit goes to git writer.

like image 34
M.Rizwan Avatar answered Oct 24 '22 07:10

M.Rizwan