Create products Google play and in-app billing

Viewed 1186

I'm doing an app that have a RecyclerView with many items (some of them are fixed and are by default for everyone), but I'd like to make some of them "not free", means that you have to pay (if possible using Google Play) to unlock those items, can you guide to me how do I figure out this scenario? How do I know that the user has items that has paid for them, and when I know that he paid for them.

I do not want to use a Database because I only need two tables I guess, for example;

TABLE USER

Where I'll will store an id (I guess it will be the email if I finally create a Login GMAIL,FACEBOOK)

TABLE BOX

Where I'll put the BOX that are free and not free and as a Foreign Key I'll put the user.id to get references what BOX's he/she owns.

Right?

But, If I have to choose this way, because if the user pays for a box on my APP and then he want to use it in other device, it won't have the box unless he logs in on the new device, correct? So, If I had had to choose a Database and Hosting to do it, what will be your recommendation? (From start, I won't have too much data, so I don't need the best one, I only want to communicate with my Android app).

I hope it's clear now, otherwise, put a comment and I'll try to explain it better.

EDIT

Reading the answers I see that I can use Firebase, as @Haris Qureshi said, well what I'm confused is :

How do I store the product? I mean, I've read and watched videos on YouTube and I have to do it in Console of Google Play but do I need to send the .apk and then add the products?

If I do not need to create a Database, and I have to end up using Firebase, using the Storage stuff from Firebase will store my products? But I can assign it as a PURCHASED, PAID, AVAILABLE? Also I'll need to integrate the Authentication, right? Because he said that once you buy a product, it stores the gmail that has paid for it and you know who paid and not paid, so if he uses another device it will have the same products boughts (if he still with the same gmail).

The products can be dynamics? I mean, you can create for example an "event" and put that product only for x days, as I'll need an Image to show the product, I mean the product will have also an Image to show on the UI, but I see in the Console of Google Play I only can create an id for the product and if I'd have to create it dynamic I could do that, because I have to store the Images on /res/mipmap right?

EDIT2

What I need is what @Alex Mamo told to me :

You cannot store images in your Firebase database. You need to store them in Firebase Storage. In Firebase database you need to store only the urls of those images.

The flow is like this: upload image to Firebase Storage -> get the url of the corresponding image (when uploading) -> store the url in Firebase Database -> use the reference to display the image

I've created the products on google console developer, and I have to connect my app to in-app billing

9 Answers

There are good answers here but because you have asked me, i'll try to give you some more details. The best practice for Implementing In-app Billing is the official documentation. Please se below my my answer for some of your questions.

As many other users have advised you, so do I, use Firebase as your database for your app. It's a NoSQL database and it's very easy to use.

How do you store the product?

Please see below a database structure that i recomand you to use for your app.

Firebase-root
    |
    --- users
    |     |
    |     --- uid1
    |          |
    |          --- //user details (name, age, address, email and so on)
    |          |
    |          --- products
    |                |
    |                --- productId1 : true
    |                |
    |                --- productId2 : true
    |
    --- products
    |     |
    |     --- productId1
    |     |     |
    |     |     --- productName: "Apples"
    |     |     |
    |     |     --- price: 11
    |           |
    |           |
    |           --- users
    |                |
    |                --- uid1: true
    |                |
    |                --- uid2: true
    |
    --- purchasedProducts
         |      |
         |      --- uid1
         |           |
         |           --- productId1: true
         |           |
         |           --- productId2: true
         |
         --- paidProducts
         |      |
         |      --- uid2
         |           |
         |           --- productId3: true
         |
         --- availableProducts
         |      |
         |      --- uid3
         |           |
         |           --- productId4: true

Using this database structure you can query your database for:

  1. All products (purchased, paid or available) that belong to a single user
  2. All users that have bought a particular product
  3. All purchased products that belong to a single user
  4. All paid products that belong to a single user
  5. All available products that belong to a single user

Every time a product is bought, you only need to move the product to the coresponding category. As AL. said, you could set your app to get the products by using the Firebase SDK. That would not be a problem.

This is called in Firebase denormalization is very normal with the Firebase Database. For this, i recomand see this video. If you want something more complex, i recomand you read this post, Structuring your Firebase Data correctly for a Complex App.

Using the Storage stuff from Firebase will store my products?

Yes, you can use Firebase Cloud Storage which is built for app developers who need to store and serve user-generated content, such as photos or videos.

Also I'll need to integrate the Authentication, right?

Yes, you need to use Firebase Authentication because you need to know the identity of a user. Knowing a user's identity allows an app to securely save user data in the cloud and provide the same personalized experience across all of the user's devices. Firebase Authentication provides backend services, easy-to-use SDKs, and ready-made UI libraries to authenticate users to your app. It supports authentication using passwords, phone numbers, popular federated identity providers like Google, Facebook and Twitter, and more.

The products can be dynamics? I mean, you can create for example an "event" and put that product only for x days?

Yes, you can do that using Cloud Functions For Firebase which lets you automatically run backend code in response to events triggered by Firebase features and HTTPS requests. Your code is stored in Google's cloud and runs in a managed environment. There's no need to manage and scale your own servers.

This is how you can query the database to display the product name and the price of all products.

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference yourRef = rootRef.child("products");
ValueEventListener eventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            String productName = ds.child("productName").getValue(String.class);
            double price = ds.child("price").getValue(Double.class);
            Log.d("TAG", productName + price);
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {}
};
yourRef.addListenerForSingleValueEvent(eventListener);

And this how you can query your database to see all purchasedProducts that belong to a specific user:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference uidRef = rootRef.child("purchasedProducts").child("uid1");
ValueEventListener eventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            String productKey = ds.getKey();
            Log.d("TAG", productKey);
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {}
};
uidRef.addListenerForSingleValueEvent(eventListener);

For each row of the RecyclerView define a TextView to indicate the three status (i.e. :- "Free" ,"Pay", "PAID") of this particular item on the side of the row. You can make the TextView with the status of "Pay" clickable dynamically if you want the user navigate to purchase screen.

Now define an Adapter for the RecyclerView and within that have an enum with three status (i.e. :- "FREE","NOT_PAID", "PAID") to indicate the status of the current item and a property to hold the enum value. When the Activity starts fill up that property (enum type) according to the back-end data for particular items dynamically. Based on the value you can change the status of the TextView (i.e. :- "Free" ,"Pay", "PAID") dynamically. That logic also should goes on the Adapter.

Hope you can have the implementation based on the above suggestion. I can provide an implementation if you need further help.

Add all your products in google play store as in app purchase products.

Pseudocode

  1. Create a class say Products having data members as productID, productType, price, description, tag, etc.

  2. Query for items available for purchase and save them in your Products with tag AVAILABLE.

  3. Query for purchased items and save them with tag PURCHASED.

  4. Use Firebase to get free products and store them with tag FREE.

  5. Populate your RecyclerView with given ArrayList and show your TextView accordingly in your adapter.

Google stores all purchase history but if you want to add more products you need to add products in google console as well publish new android version.

For more details see this example.

Saw your comment from here. I paid attention to the edited part. Here's my two cents:

How do I store the product? I mean, I've read and watched videos on YouTube and I have to do it in Console of Google Play but do I need to send the .apk and then add the products?

You could store it directly from the Firebase Console. Afterwards, you could set your app to get the products by using the Firebase SDK. If you already have the app uploaded on Google Play, I think you just need to upload the updated APK that could perform the data retrieval (using the Firebase SDK).

If I do not need to create a Database, and I have to end up using Firebase, using the Storage stuff from Firebase will store my products? But I can assign it as a PURCHASED, PAID, AVAILABLE? Also I'll need to integrate the Authentication, right?

If I understand your requirement correctly, you would most certainly need a database. It would be easier for you to organize the products that way. From the (Firebase) Database itself, you could also put the user details there, set if they are already PAID or just using the app for FREE, this way, it'd be easier to check which products the user could access or not.

Firebase Database would work on it's own without Firebase Auth, however, it is strongly suggested to use it together, to make use of the Security Rules.

The products can be dynamics? I mean, you can create for example an "event" and put that product only for x days, as I'll need an Image to show the product, I mean the product will have also an Image to show on the UI, but I see in the Console of Google Play I only can create an id for the product and if I'd have to create it dynamic I could do that, because I have to store the Images on /res/mipmap right?

It depends on how you implement it, but yes it is most certainly possible to create a dynamic product. You could have the product details in the DB and the image file in Cloud Storage for Firebase. You could make this dynamic by adding something like an expirationDate parameter in the product details, and when retrieving the data in your app, you could simply check if it's already expired or not.

If user swaps his mobile and login in Google Play Store with the same email he used to purchase the product on the previous mobile, then the product he purchased will be visible automatically on the new mobile.

First you need to know how to create products in your google play developer console. You can check this.

You need to upload your APK but not necessarily publish it. Once you do that along with the steps mentioned in the link I provided you will be able to create products like (wood, silver, iron) give them ids, and retrieve them whenever you need to allow a purchase (and this will be the part where firebase will help us do that).

First learn how to make your in app products and how to give them details and ids.

next I will help you to make your database in firebase and know when to allow a purchase.

UPDATE

I will assume that you already linked your app to firebase, if not then you should find out how to do it.

step 1

a) make sure to go to authentication in your firebase console and enable (sign in with email and password).

b)add the following dependencies:

  compile 'com.google.firebase:firebase-auth:11.0.2'
  compile 'com.google.firebase:firebase-database:11.0.2'

STEP 2

create your register activity call it (RegisterActivity) , for simplicity add a button (called register) and two edittext fields (call them edit1 and edit2).

now we register a user like that:

    private String email;
    private String password;
    private FirebaseAuth mauth;

     //on create
    mauth=FirebaseAuth().getInstance();


    //on click of register button 

     //get what ever was typed in edit text fields and store them like that
     email=edit1.getText().toString();
     password=edit2.getText().toString();

     //create user like that 

      math.createUserWithEmailAndPassword(email,password).addOnCompleteListener(new OnCompleteListener<AuthResult>(){

           @Override
           public void onComplete(@NonNull Task< AuthResult> task){
             //on complete store users in database
             if(task.isSuccessful()){ 
              //get the user uid
               FirebaseUser user=FirebaseAuth.getInstance().getCurrentUser();
               String uid=user.getUid();

                //create a reference called my users in database
                DatabaseReference users=FirebaseDatabase.getInstance().getReference().child("my_users");

                 users.child(uid).setValue("user");//you can attach on complete here and if task successful go to main activity.


             }

            }

       });

Step 3

Now you can make a login activity call it (LoginActivity) also it will 1 login button and 2 edited fields. And you login like that

       private String email;
       private String password;
       private FirebaseAuth mauth;

         //on create
mauth=FirebaseAuth().getInstance();


       //on click login

         math.signInUserWithEmailAndPassword(email,password).addOnCompleteListener(new OnCompleteListener<AuthResult>(){

       @Override
       public void onComplete(@NonNull Task< AuthResult> task){
         //on complete store users in database
         if(task.isSuccessful()){ 
          //get the user uid
           FirebaseUser user=FirebaseAuth.getInstance().getCurrentUser();
           String uid=user.getUid();

            if(user!=null){
               //this means your user is registered so make intent to login activity
             }

         }

        }

   });

note: always in login or register activity get the user like I did and check if he/she is null and accordingly pass the user to either login or register.

step 4

(so until now you are able to create users and store their ids in database).

now create an activity having a recycler view displaying your items like (wood, iron, silver....) or whatever and here is the trick (keep in mind that in this activity the user has already signed in to your app).

the trick: now you listen to when user clicks an item and you listen to a node called (wood) or (iron) or (silver) and if these nodes have the current user id then the user already purchased and if not then the user didn't purchase(this is where you make a pop up of the in app purchase...)

here is how to go about this:

           //in the activity of your listed items
            private FirebaseAuth mauth;
            private String currentuser:

            //on create

            mauth=FirebaseAuth().getInstance();
            //store the id of the current logged in user
            currentuser=mauth.getCurrentUser().getUid();

           //on click of an item (wood or  silver or  iron ....)

           //I will do the wood case and you do same for others

           //on click of wood item 

            DatabaseReference wood=FirebaseDatabase.getInstance().getReference().child("Wood");

             //check if user is inside wood

              wood.addListenerForSingleValueEvent(new ValueEventListener(){

                @Override
                public void onDataChange(DataSnapShot datasnapshot){

                     //inside here you check if user is in wood
                      if(datasnapshot.hasChild(currentuser)){

                         //this means user purchased the wood item
                       }else{


                        //user didn't purchase a wood item

                        //handle payment 
                        //after payment of wood is completed

                        //store user in wood node

                  DatabaseReference wood=FirebaseDatabase.getInstance().getReference().child("Wood");

         wood.child(currentuser).setValue("purchased");




                       }

                   }

               });

Regarding firebase you have to do this:

First Firebase is a nosql database so it uses JSON to add values to the database. Also Firebase is a service that has realtime database,storage,cloud functions,authentication.So its your best option.

Now Regarding the way to store, you can do this:

In realtime Database

{
  Users:{
    push_id_here{
          name:peter
          password:a_password_here
          email: email_here
              }
    push_id_here{
          name:john
          password:a_pass_here
          email: email_here
       }
     }

     Box:{
        push_id_here{
              productname: productx
              availability: available
              image: image_url_here
                     }
         push_id_here1{
                 productname: producty
                 availability:free
                 image: image_url_here
                     }
             }

First yes authenticate the user, regarding image send it to storage and add it in database, this is probably your best option.

Push_id_here: is basically a random id generated for each node, its like a primary key.

You do it like this:

DatabaseReference ref=getInstance().getReference().child("Users").push();

the Push() will create a random id. The above is the realtime database, to create it you have to connect to firebase in the android studio.

In android studio go to Tools>Firebase>realtime database and connect to database.

to send data to database you can do this:

 DatabaseReference ref=getInstance().getReference().child("Users").push();
 ref.child("name").setValue(name) //name that you can get from `Editext`
 ref.child("email").setValue(email)

Regarding authenticate, you have to also connect to firebase authenticate, go to Tools>Firebase> firebase authenticate and enable.

Authentication means it will be authenticated in firebase, usually it authenticate email and password, there is also phone authentication. To authenticate you can add this in your code:

firebaseAuth.signInWithEmailAndPassword(email,password)
        .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {


                if(task.isSuccessful()){
                    //code here
                }else{
                    Log.e("ERROR",task.getException().toString());
                    Toast.makeText(LoginActivity.this, task.getException().getMessage(),Toast.LENGTH_LONG).show();
                }
            }
        });

example:

Sample db

In this db Klx0N4pxsBHGVkhYuY0 is a push id and channels is like Users in the JSON I gave

in order to handle dynamic products, you need a web application, which has no direct relation to the Android application, but it's backend system (only to control the release process), which interfaces ...

a) with the backend system of the application, whether it may be FireStore (in order to handle product images as "document") - or even Cloud Functions, loading the product feed through the Google Play Developer API and then delivering it as JSON to the end-devices (Cloud Functions would also permit inserting into Firebase)... however, the product images would need to be cached locally (in the internal storage, not the resources).

b) with the Google Play Developer API, in order to manage in-app products and/or consumables.

eg. when one launches an in-app product with the web-application, it would insert the product into the Play Store, to make it generally known & the FireStore, to make it visible and purchasable, from within the Android app (or with Cloud Functions, it would load an updated product feed from the API, with the same effect).

you can sharedpreferences and that will be an easy way out. when the user logged in you can retrieve his paid box id (depending upon your table) from the response.when creating recyclerView you can check for the item if it is paid and is stored in sharedpreferences.

inside bindViewHolder function of recyclerview check for the following pseudocode

  1. if item == "paid" && item exist in sharedprefrences list make it clickable (or something you want)
  2. if it is not (else part) then go to payment page.
Related