13

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());
Skizo-ozᴉʞS ツ
  • 19,464
  • 18
  • 81
  • 148
  • `but now when I download it from Google Play` To what? – greenapps Apr 25 '18 at 12:52
  • [Have a look at this thread](https://stackoverflow.com/a/33324791/681929) – nobalG Apr 25 '18 at 12:52
  • 1
    @greenapps to real device or emulator, before that he was doing it directly from Android Studio – nobalG Apr 25 '18 at 12:53
  • Exactly, I was running it with emulator and my real device, but when I download it from Google Play it crashes... – Skizo-ozᴉʞS ツ Apr 25 '18 at 12:55
  • @nobalG I'm updating all the stuff on my build.gradle... let's see, but I have to make an update on my app everytime Firebase (for example) makes an update and I have to increase the number build???? – Skizo-ozᴉʞS ツ Apr 25 '18 at 12:57
  • 1
    If you want to see the correct way for getting data from a Firebase Realtime database and display it in a `RecyclerView` using `FirebaseRecyclerAdapter`, **[this](https://stackoverflow.com/questions/49383687/how-can-i-retrieve-data-from-firebase-to-my-adapter/49384849)** is how you can do it. – Alex Mamo Apr 25 '18 at 12:59
  • Hello @AlexMamo, I was thinking to do this, but I have stuff like InAppPurchase on same activity and I have to controll it in the same activity... – Skizo-ozᴉʞS ツ Apr 25 '18 at 13:01
  • @Skizo-ozᴉʞS That's ok. You can implement the way it is explained in that post in then just add the stuff like InAppPurchase and so on. – Alex Mamo Apr 25 '18 at 13:05
  • @AlexMamo but I have to change the implementatios everytime I see them yellow? I mean I had 12.0.0 and now I upgraded to 15.0.0 do I have to upload my app everytime I do this?, check my edit I'll post my implementations – Skizo-ozᴉʞS ツ Apr 25 '18 at 13:09
  • It's not mandatory but it is recommended to use the latest version for all your dependencies. Have you tried my solution? – Alex Mamo Apr 25 '18 at 13:12
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/169765/discussion-between-skizo-oziks-and-alex-mamo). – Skizo-ozᴉʞS ツ Apr 25 '18 at 13:15
  • check this: https://stackoverflow.com/questions/29141729/recyclerview-no-adapter-attached-skipping-layout – Peter Haddad Apr 25 '18 at 13:16
  • Did you tested the app-release.apk before uploading to Google Play? It may be a proguard issue. – Marcos Vasconcelos Apr 25 '18 at 13:33
  • 1
    You should be using [firebase-ui-database:3.3.1](https://github.com/firebase/FirebaseUI-Android/releases) for compatibility with Firebase SDK 15.0.0. – Bob Snyder Apr 25 '18 at 13:44
  • @BobSnyder Good point – Skizo-ozᴉʞS ツ Apr 25 '18 at 13:59
  • @MarcosVasconcelos Yes, I did it, and the problem is that I can not loggin to my account – Skizo-ozᴉʞS ツ Apr 26 '18 at 12:23
  • @AlexMamo Do you know why I'm building the signed apk and when I install it to my device (Without Google Play) I can't even login? People said that I have to update the SHA-1???? – Skizo-ozᴉʞS ツ Apr 27 '18 at 09:09
  • @Skizo-ozᴉʞS Yes, that's correct. – Alex Mamo Apr 27 '18 at 11:05
  • @AlexMamo Yes, look my last edit, I found where it crashes with Toast debug... it crashes when trying to add products seems like query is not ok, but if I run the app from Android Studio the query is ok... don't get it... – Skizo-ozᴉʞS ツ Apr 27 '18 at 13:02
  • Do you properly check for all Google Play Versions up to date to match your app's versions compiled into your binary? You can't assume that every device has the appropriate Google Play Services to match your application. You must validate that on first launch. – Sam May 01 '18 at 15:34
  • @Sam What do you mean? I'm saying that if I run the app from my android studio is ok, if I generate the signed APK it says that can not login, and if I upload on Google Play It crashes on my last edit – Skizo-ozᴉʞS ツ May 01 '18 at 15:39
  • ok so are you saying that when you install from Android Studio on the "SAME EXACT" device, it works fine no problem, but when you generate an APK and install it through ADB it fails to login? – Sam May 01 '18 at 15:42
  • SAME AXACT or a new device new emulator the app is working ok, but when I try to install it from .apk it starts to crash, and when I upload it to Google Play logins works ok, but then comes the error (last edit) – Skizo-ozᴉʞS ツ May 01 '18 at 15:46
  • Have you tried all variations from Android Studio? You can change the build variant from the lower left fly out menu. Have you confirmed the build variant installs and works fine that you are compiling for release, if you do it from Android Studio directly in the build variant menu? Also, can you share the error logs that you see during the crash of the APK that fails. – Sam May 01 '18 at 15:59
  • Did you try a "clean" before "build a signed apk"? – Alessandro Verona May 02 '18 at 06:45
  • Of course I did it, and no success – Skizo-ozᴉʞS ツ May 02 '18 at 06:49
  • Have tried manually installing signed apk on the device? – Burhanuddin Rashid May 03 '18 at 04:54
  • What do you mean with mannually? – Skizo-ozᴉʞS ツ May 03 '18 at 06:32
  • Install the apk which you use to upload to the play store manually by adb command line – Burhanuddin Rashid May 03 '18 at 10:27
  • Yes I did it but now with adb... is it different to use adb or installing mannually? – Skizo-ozᴉʞS ツ May 03 '18 at 10:44
  • may be a issue in client ID – Ishan Fernando May 03 '18 at 18:25
  • Tried to login with other account @IshanFernando – Skizo-ozᴉʞS ツ May 03 '18 at 20:38
  • the logcat says directly that you are missing the class while inflating the design ! I propose the solution check that out! and the error regarding that its not working on device from store the issue is when you release an apk it gets its own powers decapitated which it posses in debug mode ! so I guess this issue was something with that! on api >23 this will be no issue and below that there is the issue! so my solution kinda gives the right perspective or so – Rizwan Atta May 04 '18 at 13:08
  • @AlexMamo Do you know how to get context instead of parent.getContext()? See Rizwan atta answer please – Skizo-ozᴉʞS ツ May 04 '18 at 14:51
  • @Skizo-ozᴉʞS Yes, you can define a global variable `Context context` and intialize it in the onCreate method like this: `context = this`. I then just use the conect variable where is nedded. Does it work? – Alex Mamo May 04 '18 at 15:13
  • @AlexMamo I tried with getAplicationContext() instead and is the same error... if I do with a global variable it says it must be final since it's accesible on an inner stuff – Skizo-ozᴉʞS ツ May 04 '18 at 15:57
  • @Skizo-ozᴉʞS A global variable means that is defined at the beginning of your class, right? – Alex Mamo May 04 '18 at 15:59
  • I cna try to upload the version with a global variable... but wouldn't do the same getApplicationContext() and this? – Skizo-ozᴉʞS ツ May 04 '18 at 16:04

4 Answers4

2

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

if ("your_component" != null){
//your code
}
2

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).
Aman B.
  • 138
  • 4
  • 12
2

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.

Skizo-ozᴉʞS ツ
  • 19,464
  • 18
  • 81
  • 148
  • 1
    I'm facing the exact same issue. Where did you use the @Keep? on the entire Fragment that uses the firebase database? – Avital May 19 '21 at 13:24
  • Feel free to open a new question and add information so I can take a look :) – Skizo-ozᴉʞS ツ May 20 '21 at 10:29
  • Same problem here!! Im trying to get data from wordpress and it works in my cellphone (when running from my laptop) but not when I uploaded it to Google Play – Maduro Sep 03 '21 at 21:33
1

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.

Rizwan Atta
  • 3,222
  • 2
  • 19
  • 31
  • So you are saying 2 ways to do it, right? parent.getContext() and passing the context itself on constructor? – Skizo-ozᴉʞS ツ May 04 '18 at 14:38
  • parent.getContext won't work it is the main cause of exception here! try changing the way of context getting and I hope will work – Rizwan Atta May 04 '18 at 14:39
  • But I have adapter like this : 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); return new CardHolder(view); } – Skizo-ozᴉʞS ツ May 04 '18 at 14:42
  • How do I pass context by parameter? – Skizo-ozᴉʞS ツ May 04 '18 at 14:42
  • make a new class extend its FirebaseRecyclerAdapter and try making the constructor there ^_^ – Rizwan Atta May 04 '18 at 14:44
  • Can't do this at the moment... I have a lot to touch, I'd need a simple solution to how to get the real context, and if it works, I can publish my app and then I can go through clean code – Skizo-ozᴉʞS ツ May 04 '18 at 14:51
  • as you are using it directly in the activity I suppose so you can use directly this as gettApplicationContext() at layoutInflator.from(getApplicationContext()); its a long shot but it will do it – Rizwan Atta May 04 '18 at 14:53
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/170384/discussion-between-rizwan-atta-and-skizo-oziks). – Rizwan Atta May 04 '18 at 14:53
  • or you can try it like layoutInflator.from(YourActivityName.this) – Rizwan Atta May 04 '18 at 14:54