Firebase JobDispatcher Background Service

We need background service for executing many task. For instance geo location, cloud messaging or to execute heavy task which cannot be done during android lifecycle. Some background service might not run for so long that’s why google created this library for doing long running task which is Firebase jobDispatcher.

What is a Firebase JobDispatcher or job Scheduler?

The JobScheduler is an Android system service available on API levels 21 (Lollipop)+. It provides an API for scheduling units of work (represented by jobservice subclasses) that will execute in your app’s process.

Why is this better than background services and listening for system broadcasts?

Running apps in the background is expensive, which is especially harmful when they’re not actively doing work that’s important to the user. That problem is multiplied when those background services are listening for frequently sent broadcasts (android.net.conn.CONNECTIVITY_CHANGE and android.hardware.action.NEW_PICTURE are common examples). Even worse, there’s no way of specifying prerequisites for these broadcasts. Listening for CONNECTIVITY_CHANGE broadcasts does not guarantee that the device has an active network connection, only that the connection was recently changed.

How to Integrate Firebase JobDispatcher Background Service?

So lets start. The official github repo is here and the implemented code is here

  • implement this code in app.gradle implementation ‘com.firebase:firebase-jobdispatcher:0.8.5’
  • add below code to manifest.
<service
android:name=".FirebaseJobDispatcher.DemoJobService"
android:exported="false">
<intent-filter>
<action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE" />
</intent-filter>
</service>
  • add FirebaseJobDispatcher folder to your project.
  • initialize service on mainactivity to start the job.
void ScheduleJob(){

try {
FirebaseJobDispatcher jobDispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(MainActivity.this));

final Job.Builder builder = jobDispatcher
.newJobBuilder()
.setTag("Repetitive")
.setRecurring(false)
.setLifetime(Lifetime.FOREVER)
.setService(DemoJobService.class)
.setReplaceCurrent(false)
.setRetryStrategy(
jobDispatcher.newRetryStrategy(
RetryStrategy.RETRY_POLICY_EXPONENTIAL,
30,
3600));

builder.setConstraints(Constraint.ON_ANY_NETWORK,Constraint.DEVICE_IDLE);
builder.setTrigger(
Trigger.executionWindow(60, 60 + 50));
jobDispatcher.mustSchedule(builder.build());
}catch (Exception e){
e.printStackTrace();

}
}
  • By calling this you can start the job
  • And in DemoJobService ononStartJob you can define your job
  • I have created a notification service just for example you can create any other service with this.
DemoJobService
Sample notification

Upload image on Firebase storage

Upload image on Firebase storage Uploading an image to any server is quite a hectic task and it also as for so much of memory and processing time on the front end. This can be achieve with new RxJava By using this we can create multiple task with quite a minimum time.

What is Firebase Storage?

Cloud Storage for Firebase lets you upload and share user generated content, such as images and video, which allows you to build rich media content into your apps. Your data is stored in a Google Cloud Storage bucket, an exabyte scale object storage solution with high availability and global redundancy. Cloud Storage lets you securely upload these files directly from mobile devices and web browsers, handling spotty networks with ease.

Why RxJava?

RxJava is a Java VM implementation of Reactive Extensions: a library for composing asynchronous and event-based programs by using observable sequences.

How to upload image on firebase

How to Upload image on Firebase storage

1- First you need to add the android app to Firebase Console if not done yet you can get through this from here.

2- Add firebase storage to your firebase console.

3- In this tutorial we are using dexter for permission and glide.

4- Add Some helper class For camera upload CameraIntent.java and helper.java.

5- Add layout file activity_sign_up.xml.
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/app_bar_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        android:fitsSystemWindows="true">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="250dp"
            android:fitsSystemWindows="true"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            >

            <androidx.appcompat.widget.AppCompatImageView
                android:layout_width="match_parent"
                android:layout_height="250dp"
                android:id="@+id/iv_profile_pic"
                android:background="@color/white"
                android:fitsSystemWindows="true"
                android:contentDescription="@string/app_name"
                android:src="@mipmap/ic_profile"
                app:layout_collapseMode="parallax"/>

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/Appbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                android:title="recent_news"
                app:layout_collapseMode="pin" />
        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>


    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/iv_profile_pic_select"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:clickable="true"
        app:elevation="6dp"
        android:src="@drawable/upload_button"
        app:pressedTranslationZ="12dp"
        app:layout_anchor="@id/app_bar_layout"
        app:layout_anchorGravity="bottom|right|end"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

6- Now signup activity.

Create a function for upload image

private UploadTask saveImage(Bitmap image_bitmap_load, StorageReference storage, String file_name_small,int type) {

    //Play with bitmap
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    image_bitmap_load.compress(Bitmap.CompressFormat.JPEG, 100, baos);
    final byte[] data = baos.toByteArray();
    Date date = new Date();

    final StorageReference ref = storage.child(file_name_small);
    UploadTask  uploadTask = ref.putBytes(data);

    Task<Uri> urlTask = uploadTask.continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
        @Override
        public Task<Uri> then(@NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
            if (!task.isSuccessful()) {
                Toast.makeText(SignUpActivity.this, "unable to upload", Toast.LENGTH_SHORT).show();

                throw task.getException();
            }


            return ref.getDownloadUrl();
        }
    }).addOnCompleteListener(new OnCompleteListener<Uri>() {
                                 @Override
                                 public void onComplete(@NonNull Task<Uri> task) {
                                     if (task.isSuccessful()) {
                                         Uri downloadUri = task.getResult();

                                     } else {
                                         // Handle failures
                                         Toast.makeText(SignUpActivity.this, "unable to upload", Toast.LENGTH_SHORT).show();

                                     }
                                 }
                             }
    );
    return uploadTask;


}
7- And initialize observable
private final CompositeDisposable disposables = new CompositeDisposable();

Observable<UploadTask> sampleObservable(final UploadTask large_image_task, final UploadTask normal_image_task, final UploadTask small_image_task) {
    StorageReference storage = FirebaseStorage.getInstance().getReference();
    return Observable.defer(new Callable<Observable<UploadTask>>() {
        @Override public Observable<UploadTask> call() throws Exception {
            // Do some long running operation
            //   SystemClock.sleep(5000);

            return Observable.just(large_image_task,normal_image_task,small_image_task);
        }
    });
}

8- Add task to disposables

disposables.add(sampleObservable(large_image_task,normal_image_task,small_image_task)
// Run on a background thread
.subscribeOn(Schedulers.io())
// Be notified on the main thread
.observeOn(AndroidSchedulers.mainThread())

.subscribeWith(new DisposableObserver<Task>() {
@Override public void onComplete() {
Log.d(TAG, "onComplete()");

}

@Override public void onError(Throwable e) {
Log.e(TAG, "onError()", e);
}

@Override public void onNext(Task task) {
Log.d(TAG, "onNext(" + task + ")");
}
}));

It will trigger oncomplete File will be uploaded to the firebase storage. You can comment below for any queries. You can also get the code from here.

That’s all for how to upload image using Rx java.

Tagged : /

Connect your Android phone wirelessly by adb

Android Debug Bridge (adb) is a versatile command-line tool that lets you communicate with Android phone or device. On how to Connect your android phone wirelessly by adb you can follow below steps.

Setting up environment variable for adb platform tools by Android sdk

  • For this I am considering you have already installed the latest version of Android studio. If not you can download it from here.
  • You can get the sdk location from.
Connect your android phone wirelessly by adb
Sdk location from sdk manager

You can set the platform tools path in environment variable (optional).

Now, go to the skd location/platform-tools from cmd. Process the following command to

Connect your android phone wirelessly by adb

  • Make sure your device and pc connected to same network.
  • plug in the data cable from pc to device.
  • Now, type adb tcpip 5555
  • remove data cable.
  • Then type adb connect 192.168.43.95
  • here 5555 is the port number and 192.168.43.95 is the ip address of the mobile device you can get id address from the mobile settings . Then go to About device and go to status you can see the ip address of the device.
  • You can connect multiple device from different ports which can give ease in development.

Hope, It works if not don’t forgot to comment below .

Tagged : / / / /

Add Firebase Mobile Authentication

Why we need to add Firebase mobile Authentication in Android Application?

Mobile authentication is much needed nowadays to verify the user authentic information land to remove the fake users and to get the credibility of the user. You can easily track the user by the mobile number and put all checks to you’r system. Someone can put a random number and access you’r data which will hurt you’r business and put you’r data at much higher risk.

1- First you need to add the android app to Firebase Console if not done yet you can get through this from here.

2- Go to Firebase console > Authentication > Sign In Methods and enable phone authentication.

Firebase mobile authentication

You can also add testing numbers for development purpose and the authentication key . So let’s get started on add Firebase mobile authentication android on android studio.

3- For production purpose you also need to add the SHA 1 certificate fingerprints. To get the fingerprints go to project > gradle > project > android > signin reports then you can get the fingerprint from bottom on the screen (optional).

Firebase authentication
Get SHA 1 from android studio

In app build.gradle you need to add.

implementation 'com.google.firebase:firebase-auth:19.3.0'.

Then in MainActivity.java where user enter the mobile number and country code to request the otp.

package com.example.sampleproject;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import com.google.firebase.FirebaseException;
import com.google.firebase.FirebaseTooManyRequestsException;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseAuthInvalidCredentialsException;
import com.google.firebase.auth.PhoneAuthCredential;
import com.google.firebase.auth.PhoneAuthProvider;

import java.util.concurrent.TimeUnit;

public class MainActivity extends AppCompatActivity {

private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks;
private FirebaseAuth mAuth;
private Helper helper;
private UserModel mUser = new UserModel();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
helper= new Helper(this);
phoneAuth();
Button bt_login = (Button) findViewById(R.id.bt_login);
final EditText et_mobile_no = (EditText) findViewById(R.id.et_mobile_no);
final EditText et_country_code = (EditText) findViewById(R.id.et_country_code);

bt_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String mobile_no = et_mobile_no.getText().toString();
String country_code = et_country_code.getText().toString();
String mobileNumber = country_code+mobile_no;
mUser.setMobile(mobileNumber);

createNewUser(mobileNumber);
}
});
}
private void phoneAuth() {
mAuth= FirebaseAuth.getInstance();

mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
@Override
public void onVerificationCompleted(PhoneAuthCredential credential) {
helper.display( "Verification complete" );
String sms_code=credential.getSmsCode();
PhoneAuthCredential credentials = credential;

}

@Override
public void onVerificationFailed(FirebaseException e) {
helper.display(" Verification Failed");
if (e instanceof FirebaseAuthInvalidCredentialsException) {
helper.display("Invalid phone number.");
} else if (e instanceof FirebaseTooManyRequestsException) {
helper.display( "Quota exceeded");
}
e.printStackTrace();
helper.hideDialog();
}

@Override
public void onCodeSent(String verificationId,
PhoneAuthProvider.ForceResendingToken token) {
helper.display( "Verification code send");
mUser.setVerificationId(verificationId);

Intent intent = new Intent(MainActivity.this, VerifyOtp.class);
intent.putExtra("user_details", mUser);
intent.putExtra("user_token", token);
startActivity(intent);
helper.hideDialog();


}

@Override
public void onCodeAutoRetrievalTimeOut(String s) {
helper.hideDialog();
super.onCodeAutoRetrievalTimeOut(s);
}
};

}
void createNewUser(String phoneNumber){

PhoneAuthProvider.getInstance().verifyPhoneNumber(
phoneNumber, // Phone number to verify
60, // Timeout duration
TimeUnit.SECONDS, // Unit of timeout
this, // Activity (for callback binding)
mCallbacks); // OnVerificationStateChangedCallbacks

}
}

Now, Verify the opt process in VerifyOtp class.

package com.example.sampleproject;

import android.content.Intent;
import android.os.Bundle;

import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseAuthInvalidCredentialsException;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.auth.PhoneAuthCredential;
import com.google.firebase.auth.PhoneAuthProvider;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import java.io.Serializable;

public class VerifyOtp extends AppCompatActivity {

private String TAG = "VerifyOtp";
private UserModel mUserModel;
private FirebaseAuth mAuth;
private Helper helper;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_data);
mAuth= FirebaseAuth.getInstance();
helper = new Helper(this);
Button bt_submit = (Button)findViewById(R.id.bt_submit);
final EditText et_otp = (EditText)findViewById(R.id.et_otp);
Intent intent = getIntent();

if (intent != null) {

Serializable userSerializable = intent.getSerializableExtra("user_details");

mUserModel = (UserModel) userSerializable;
if(mUserModel!=null) {

}else {

}
}
bt_submit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String otp = et_otp.getText().toString();

PhoneAuthCredential credential = PhoneAuthProvider.getCredential(mUserModel.getVerificationId(), otp.trim());
signInWithPhoneAuthCredential(credential);
}
});
}

private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
helper.display("Sign in successfully");
final FirebaseUser firebase_user = task.getResult().getUser();
Log.d(TAG, "onComplete: "+firebase_user.getPhoneNumber());
} else {
helper.hideDialog();
helper. display( "Unable to sign in");
if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
helper. display("Invalid code");
}
}
}
});
}

}

You can use other sign in methods available in Firebase Authentication.

Also you can download the code from here.

Tagged : / /

Android app pass data between activities

Passing Data types like String, Integer, Float, double is quite easy in android so we don’t need any special class for this. But for Android pass model from intents using Serializable from intents we need Serializable class.

What is Modal Class

Model can be applied to a class which represents your application’s data model, and will cause instances of the class to become observable, such that a read of a property of an instance of this class during the invocation of a composable function will cause that component to be “subscribed” to mutations of that instance. Composable functions which directly or indirectly read properties of the model class, the composables will be recomposed whenever any properties of the the model are written to.

What is Serializable?

It is a standard Java interface. So you can just implement Serializable interface and add override methods.

There are pros and cons of this class. It is comparatively slow and easy to integrate.

To immplements simple Data types we can just pass ‘Xyz’ by key ‘name’.

Intent intent = new Intent(MainActivity.this, DataActivity.class);
intent.putExtra("name","Xyz");// for string variable 

And in data activity to fetch the data by key ‘name’.

Intent intent = getIntent();
intent.getStringExtra("name");// to fetch data

But for passing objects or model class we need serialization.

So let’s get started on how Android app pass data between activities.

For this section I have created MainActivity, DataActivity and UserModel to achieve the task.

MainActivity.java

To send the model class from MainActivity to DataActivity class by using Serializable class.

package com.example.sampleproject;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ((Button)findViewById(R.id.click_me)).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                UserModel mUser = new UserModel();
                mUser.setId(1);
                mUser.setName("Xyz");
                mUser.setMobile("99919290XX");

                Intent intent = new Intent(MainActivity.this, DataActivity.class);
                intent.putExtra("name","Xyz");
                intent.putExtra("user", mUser);
                startActivity(intent);
            }
        });

    }
}

DataActivity.java

To fetch the model class from main activity.

package com.example.sampleproject;

import android.content.Intent;
import android.os.Bundle;

import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import android.util.Log;
import android.view.View;

import java.io.Serializable;

public class DataActivity extends AppCompatActivity {

    private String TAG = "DataActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_data);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        Intent intent = getIntent();
        if (intent != null) {

            Serializable s = intent.getSerializableExtra("user");
            UserModel mUserModel = (UserModel) s;
            if(mUserModel!=null) {
                int id = mUserModel.getId();
                String name = mUserModel.getName();
                String mobile = mUserModel.getMobile();
                Log.d(TAG, "id: "+id);
                Log.d(TAG, "name: "+name);
                Log.d(TAG, "mobile: "+mobile);
            }else {

            }
        }
    }

}

UserModel.java

Model which is shared between the MainActivity and DataActivity class.

You can also add child model or list of UserModel class just you have to implements that model by Serializable.

package com.example.sampleproject;

import java.io.Serializable;

public class UserModel implements Serializable {

    private int id;
    private String name;
    private String mobile;


    public void setId(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setMobile(String mobile) {
        this.mobile = mobile;
    }

    public String getMobile() {
        return mobile;
    }
}

Output of Android app pass data between activities:

The output of this code will look like this.

id: 1.
name: Xyz.
mobile: 99919290XX.

You can also see this post where I have passed a model class between activities by using intents from here.

Tagged : / / / /

Add Android app to Firebase Crashlytics

On How to Add Android app to Firebase Crashlytics. You have to follow the below steps. First you need to understand the importance of Crashlytics. Suppose you have a large number of active users who are using you’r application so if any error occurs you need the source of that error and debug accordingly both in development and production. So Don’t worry sit tight Firebase is there for you for debugging.

What is Firebase Crashlytics?

Firebase Crashlytics is a lightweight, realtime crash reporter that helps you track, prioritize, and fix stability issues that erode your app quality. Crashlytics saves you troubleshooting time by intelligently grouping crashes and highlighting the circumstances that lead up to them.

Add Android app to Firebase Crashlytics

  1. If not done in previous app you can go through this Connect your Android app to Firebase Console.
  2. Click on Crashlytics under Quality in Firebase console.
  3. Click this app is new to Crashlytics .

Add Crashlytics SDK

  1. In your project bild.gradle add
buildscript {
    repositories {

        // Add Google's Maven repository.
        google()

        maven {
           url 'https://maven.fabric.io/public'
        }

    }

    dependencies {
        // ...

        // Add the Google Services plugin (check for v3.1.2 or higher).
        classpath 'com.google.gms:google-services:4.3.3'

        // Add the Fabric Crashlytics plugin.
        classpath 'io.fabric.tools:gradle:1.31.2'


    }
}


allprojects {
    // ...

    repositories {

       // Check that Google's Maven repository is included (if not, add it).
       google()


       // ...
    }
}




2. Add your app level build.gradle.

apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'
// Add the Fabric plugin.
apply plugin: 'io.fabric'


dependencies {
    // ...

    // (Recommended) Add the Google Analytics dependency.
    implementation 'com.google.firebase:firebase-analytics:17.2.3'

    // Add the Firebase Crashlytics dependency.
    implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'

}

3. Change min Sdk version to 16 in app level build.gradle.

Add an error to report

add this code in MainActiviety.

int[] error = new int[-1];// add an error to listen

Github

You can get the repository from here.

Tagged : / / / / / / /

Connect your Android App to Firebase Database

On how to Connect your Android App to Firebase Database just follow the below steps.

Installation & Setup

1. But first you have to setup a Firebase project and follow the screen instructions firebase console.

2.Then Navigate to database section and create one and click on create database > test mode to access > enable.

3.Go to project Overview > Project settings > General > click on android icon in your apps.

4.Register your app and download google-services.json and paste it inside project > app.

5. Then in Project-level build.gradle add the following code.

buildscript {
  repositories {
    // Check that you have the following line (if not, add it):
    google()  // Google’s Maven repository
  }
  dependencies {
    …
    // Add this line
    classpath ‘com.google.gms:google-services:4.3.3’
  }
}

allprojects {
  …
  repositories {
    // Check that you have the following line (if not, add it):
    google()  // Google’s Maven repository
    …
  }
}

6. In App-level build.gradle add.

apply plugin: ‘com.android.application’
// Add this line
apply plugin: ‘com.google.gms.google-services’

dependencies {
  // add the Firebase SDK for Google Analytics
  implementation ‘com.google.firebase:firebase-analytics:17.2.2’
  // add SDKs for any other desired Firebase products
  // https://firebase.google.com/docs/android/setup#available-libraries
}

7. now click on sync now in the Android Studio.

Now, Run your project for Connect your Android App to Firebase Database.

8. copy this refrence of code to onCreate of MainActivity class .

FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("message");

myRef.setValue("Hello, World!");

Now, run the app to print the hello world in your console.

You can access the Github code from here.

Tagged : / / / /