# Firebase

Firebase is a mobile and web application platform with tools and infrastructure designed to help developers build high-quality apps.

Features

Firebase Cloud Messaging, Firebase Auth, Realtime Database, Firebase Storage, Firebase Hosting, Firebase Test Lab for Android, Firebase Crash Reporting.

# Add Firebase to Your Android Project

Here are simplified steps (based on the official documentation) required to create a Firebase project and connect it with an Android app.

# Add Firebase to your app

  • Create a Firebase project in the [Firebase console](https://firebase.google.com/console/) and click **Create New Project**.
  • Click **Add Firebase to your Android app** and follow the setup steps.
  • When prompted, enter your **app's package name**.
    It's important to enter the fully qualified package name your app is using; this can only be set when you add an app to your Firebase project.

  • At the end, you'll download a `google-services.json` file. You can download this file again at any time.
  • If you haven't done so already, copy the `google-services.json` file into your project's module folder, typically `app/`.
  • The next step is to Add the SDK to integrate the Firebase libraries in the project.

    # Add the SDK

    To integrate the Firebase libraries into one of your own projects, you need to perform a few basic tasks to prepare your Android Studio project. You may have already done this as part of adding Firebase to your app.

    1. Add rules to your root-level build.gradle file, to include the google-services plugin:
    buildscript {
        // ...
        dependencies {
            // ...
            classpath 'com.google.gms:google-services:3.1.0'
        }
    }
    
    

    Then, in your module Gradle file (usually the app/build.gradle), add the apply plugin line at the bottom of the file to enable the Gradle plugin:

    apply plugin: 'com.android.application'
    
    android {
      // ...
    }
    
    dependencies {
      // ...
      compile 'com.google.firebase:firebase-core:11.0.4'
    }
    
    // ADD THIS AT THE BOTTOM
    apply plugin: 'com.google.gms.google-services'
    
    

    The final step is to add the dependencies for the Firebase SDK using one or more libraries available for the different Firebase features.

    Gradle Dependency Line Service
    com.google.firebase:firebase-core:11.0.4 Analytics
    com.google.firebase:firebase-database:11.0.4 Realtime Database
    com.google.firebase:firebase-storage:11.0.4 Storage
    com.google.firebase:firebase-crash:11.0.4 Crash Reporting
    com.google.firebase:firebase-auth:11.0.4 Authentication
    com.google.firebase:firebase-messaging:11.0.4 Cloud Messaging / Notifications
    com.google.firebase:firebase-config:11.0.4 Remote Config
    com.google.firebase:firebase-invites:11.0.4 Invites / Dynamic Links
    com.google.firebase:firebase-ads:11.0.4 AdMob
    com.google.android.gms:play-services-appindexing:11.0.4 App Indexing

    # Updating a Firebase users's email

    public class ChangeEmailActivity extends BaseAppCompatActivity implements ReAuthenticateDialogFragment.OnReauthenticateSuccessListener {
    
        @BindView(R.id.et_change_email)
        EditText mEditText;
        private FirebaseUser mFirebaseUser;
    
        @OnClick(R.id.btn_change_email)
        void onChangeEmailClick() {
    
            FormValidationUtils.clearErrors(mEditText);
    
            if (FormValidationUtils.isBlank(mEditText)) {
                FormValidationUtils.setError(null, mEditText, "Please enter email");
                return;
            }
    
            if (!FormValidationUtils.isEmailValid(mEditText)) {
                FormValidationUtils.setError(null, mEditText, "Please enter valid email");
                return;
            }
    
            changeEmail(mEditText.getText().toString());
        }
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            mFirebaseUser = mFirebaseAuth.getCurrentUser();
        }
    
        private void changeEmail(String email) {
            DialogUtils.showProgressDialog(this, "Changing Email", "Please wait...", false);
            mFirebaseUser.updateEmail(email)
                    .addOnCompleteListener(new OnCompleteListener<Void>() {
                        @Override
                        public void onComplete(@NonNull Task<Void> task) {
                            DialogUtils.dismissProgressDialog();
                            if (task.isSuccessful()) {
                                showToast("Email updated successfully.");
                                return;
                            }
    
                            if (task.getException() instanceof FirebaseAuthRecentLoginRequiredException) {
                                FragmentManager fm = getSupportFragmentManager();
                                ReAuthenticateDialogFragment reAuthenticateDialogFragment = new ReAuthenticateDialogFragment();
                                reAuthenticateDialogFragment.show(fm, reAuthenticateDialogFragment.getClass().getSimpleName());
                            }
                        }
                    });
        }
    
        @Override
        protected int getLayoutResourceId() {
            return R.layout.activity_change_email;
        }
    
        @Override
        public void onReauthenticateSuccess() {
            changeEmail(mEditText.getText().toString());
        }
    }
    
    

    # Create a Firebase user

    public class SignUpActivity extends BaseAppCompatActivity {
    
        @BindView(R.id.tIETSignUpEmail)
        EditText mEditEmail;
        @BindView(R.id.tIETSignUpPassword)
        EditText mEditPassword;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        }
    
        @OnClick(R.id.btnSignUpSignUp)
        void signUp() {
    
            FormValidationUtils.clearErrors(mEditEmail, mEditPassword);
    
            if (FormValidationUtils.isBlank(mEditEmail)) {
                mEditEmail.setError("Please enter email");
                return;
            }
    
            if (!FormValidationUtils.isEmailValid(mEditEmail)) {
                mEditEmail.setError("Please enter valid email");
                return;
            }
    
            if (TextUtils.isEmpty(mEditPassword.getText())) {
                mEditPassword.setError("Please enter password");
                return;
            }
    
            createUserWithEmailAndPassword(mEditEmail.getText().toString(), mEditPassword.getText().toString());
        }
    
        private void createUserWithEmailAndPassword(String email, String password) {
            DialogUtils.showProgressDialog(this, "", getString(R.string.str_creating_account), false);
            mFirebaseAuth
                    .createUserWithEmailAndPassword(email, password)
                    .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                        @Override
                        public void onComplete(@NonNull Task<AuthResult> task) {
                            if (!task.isSuccessful()) {
                                Toast.makeText(SignUpActivity.this, task.getException().getMessage(),
                                        Toast.LENGTH_SHORT).show();
                                DialogUtils.dismissProgressDialog();
                            } else {
                                Toast.makeText(SignUpActivity.this, R.string.str_registration_successful, Toast.LENGTH_SHORT).show();
                                DialogUtils.dismissProgressDialog();
                                startActivity(new Intent(SignUpActivity.this, HomeActivity.class));
                            }
                        }
                    });
        }
    
        @Override
        protected int getLayoutResourceId() {
            return R.layout.activity_sign_up;
        }
    }
    
    

    # Change Password

    public class ChangePasswordActivity extends BaseAppCompatActivity implements ReAuthenticateDialogFragment.OnReauthenticateSuccessListener {
        @BindView(R.id.et_change_password)
        EditText mEditText;
        private FirebaseUser mFirebaseUser;
    
        @OnClick(R.id.btn_change_password)
        void onChangePasswordClick() {
    
            FormValidationUtils.clearErrors(mEditText);
    
            if (FormValidationUtils.isBlank(mEditText)) {
                FormValidationUtils.setError(null, mEditText, "Please enter password");
                return;
            }
    
            changePassword(mEditText.getText().toString());
        }
    
        private void changePassword(String password) {
            DialogUtils.showProgressDialog(this, "Changing Password", "Please wait...", false);
            mFirebaseUser.updatePassword(password)
                    .addOnCompleteListener(new OnCompleteListener<Void>() {
                        @Override
                        public void onComplete(@NonNull Task<Void> task) {
                            DialogUtils.dismissProgressDialog();
                            if (task.isSuccessful()) {
                                showToast("Password updated successfully.");
                                return;
                            }
    
                            if (task.getException() instanceof FirebaseAuthRecentLoginRequiredException) {
                                FragmentManager fm = getSupportFragmentManager();
                                ReAuthenticateDialogFragment reAuthenticateDialogFragment = new ReAuthenticateDialogFragment();
                                reAuthenticateDialogFragment.show(fm, reAuthenticateDialogFragment.getClass().getSimpleName());
                            }
                        }
                    });
        }
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            mFirebaseUser = mFirebaseAuth.getCurrentUser();
        }
    
        @Override
        protected int getLayoutResourceId() {
            return R.layout.activity_change_password;
        }
    
        @Override
        public void onReauthenticateSuccess() {
            changePassword(mEditText.getText().toString());
        }
    }
    
    

    # Firebase Cloud Messaging

    First of all you need to setup your project adding Firebase to your Android project following the steps described in this topic.

    # Set up Firebase and the FCM SDK

    Add the FCM dependency to your app-level build.gradle file

    dependencies {
     compile 'com.google.firebase:firebase-messaging:11.0.4'
    }
    
    

    And at the very bottom (this is important) add:

    // ADD THIS AT THE BOTTOM
    apply plugin: 'com.google.gms.google-services'
    
    

    # Edit your app manifest

    Add the following to your app's manifest:

  • A service that extends `FirebaseMessagingService`. This is required if you want to do any message handling beyond receiving notifications on apps in the background.
  • A service that extends `FirebaseInstanceIdService` to handle the creation, rotation, and updating of registration tokens.
  • For example:

    
       <service
            android:name=".MyInstanceIdListenerService">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
            </intent-filter>
        </service>
        <service
            android:name=".MyFcmListenerService">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>
    
    

    Here are simple implementations of the 2 services.

    To retrieve the current registration token extend the FirebaseInstanceIdService class and override the onTokenRefresh() method:

    public class MyInstanceIdListenerService extends FirebaseInstanceIdService {
    
        // Called if InstanceID token is updated. Occurs if the security of the previous token had been
        // compromised. This call is initiated by the InstanceID provider.
        @Override
        public void onTokenRefresh() {
            // Get updated InstanceID token.
            String refreshedToken = FirebaseInstanceId.getInstance().getToken();
    
            // Send this token to your server or store it locally
        }
    }
    
    

    To receive messages, use a service that extends FirebaseMessagingService and override the onMessageReceived method.

    public class MyFcmListenerService extends FirebaseMessagingService {
        
        /**
         * Called when message is received.
         *
         * @param remoteMessage Object representing the message received from Firebase Cloud Messaging.
         */
        @Override
        public void onMessageReceived(RemoteMessage remoteMessage) {
            String from = remoteMessage.getFrom();
    
            // Check if message contains a data payload.
            if (remoteMessage.getData().size() > 0) {
                Log.d(TAG, "Message data payload: " + remoteMessage.getData());
                Map<String, String> data = remoteMessage.getData();
            }
    
            // Check if message contains a notification payload.
            if (remoteMessage.getNotification() != null) {
                Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
            }
    
            // do whatever you want with this, post your own notification, or update local state
        }
    
    

    in Firebase can grouped user by their behavior like "AppVersion,free user,purchase user,or any specific rules" and then send notification to specific group by send Topic Feature in fireBase.
    to register user in topic use

    FirebaseMessaging.getInstance().subscribeToTopic("Free");
    
    

    then in fireBase console, send notification by topic name

    More info in the dedicated topic Firebase Cloud Messaging.

    # Sign In Firebase user with email and password

    public class LoginActivity extends BaseAppCompatActivity {
    
        @BindView(R.id.tIETLoginEmail)
        EditText mEditEmail;
        @BindView(R.id.tIETLoginPassword)
        EditText mEditPassword;
    
        @Override
        protected void onResume() {
            super.onResume();
            FirebaseUser firebaseUser = mFirebaseAuth.getCurrentUser();
            if (firebaseUser != null)
                startActivity(new Intent(this, HomeActivity.class));
        }
    
        @Override
        protected int getLayoutResourceId() {
            return R.layout.activity_login;
        }
    
        @OnClick(R.id.btnLoginLogin)
        void onSignInClick() {
    
            FormValidationUtils.clearErrors(mEditEmail, mEditPassword);
    
            if (FormValidationUtils.isBlank(mEditEmail)) {
                FormValidationUtils.setError(null, mEditEmail, "Please enter email");
                return;
            }
    
            if (!FormValidationUtils.isEmailValid(mEditEmail)) {
                FormValidationUtils.setError(null, mEditEmail, "Please enter valid email");
                return;
            }
    
            if (TextUtils.isEmpty(mEditPassword.getText())) {
                FormValidationUtils.setError(null, mEditPassword, "Please enter password");
                return;
            }
    
            signInWithEmailAndPassword(mEditEmail.getText().toString(), mEditPassword.getText().toString());
        }
    
        private void signInWithEmailAndPassword(String email, String password) {
            DialogUtils.showProgressDialog(this, "", getString(R.string.sign_in), false);
            mFirebaseAuth
                    .signInWithEmailAndPassword(email, password)
                    .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                        @Override
                        public void onComplete(@NonNull Task<AuthResult> task) {
    
                            DialogUtils.dismissProgressDialog();
    
                            if (task.isSuccessful()) {
                                Toast.makeText(LoginActivity.this, "Login Successful", Toast.LENGTH_SHORT).show();
                                startActivity(new Intent(LoginActivity.this, HomeActivity.class));
                                finish();
                            } else {
                                Toast.makeText(LoginActivity.this, task.getException().getMessage(),
                                        Toast.LENGTH_SHORT).show();
                            }
                        }
                    });
        }
    
        @OnClick(R.id.btnLoginSignUp)
        void onSignUpClick() {
            startActivity(new Intent(this, SignUpActivity.class));
        }
    
    
        @OnClick(R.id.btnLoginForgotPassword)
        void forgotPassword() {
            startActivity(new Intent(this, ForgotPasswordActivity.class));
        }
    }
    
    

    # Send Firebase password reset email

    public class ForgotPasswordActivity extends AppCompatActivity {
    
        @BindView(R.id.tIETForgotPasswordEmail)
        EditText mEditEmail;
        private FirebaseAuth mFirebaseAuth;
        private FirebaseAuth.AuthStateListener mAuthStateListener;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_forgot_password);
            ButterKnife.bind(this);
    
            mFirebaseAuth = FirebaseAuth.getInstance();
    
            mAuthStateListener = new FirebaseAuth.AuthStateListener() {
                @Override
                public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
                    FirebaseUser firebaseUser = firebaseAuth.getCurrentUser();
                    if (firebaseUser != null) {
                        // Do whatever you want with the UserId by firebaseUser.getUid()
                    } else {
    
                    }
                }
            };
        }
    
        @Override
        protected void onStart() {
            super.onStart();
            mFirebaseAuth.addAuthStateListener(mAuthStateListener);
        }
    
        @Override
        protected void onStop() {
            super.onStop();
            if (mAuthStateListener != null) {
                mFirebaseAuth.removeAuthStateListener(mAuthStateListener);
            }
        }
    
        @OnClick(R.id.btnForgotPasswordSubmit)
        void onSubmitClick() {
    
            if (FormValidationUtils.isBlank(mEditEmail)) {
                FormValidationUtils.setError(null, mEditEmail, "Please enter email");
                return;
            }
    
            if (!FormValidationUtils.isEmailValid(mEditEmail)) {
                FormValidationUtils.setError(null, mEditEmail, "Please enter valid email");
                return;
            }
    
            DialogUtils.showProgressDialog(this, "", "Please wait...", false);
            mFirebaseAuth.sendPasswordResetEmail(mEditEmail.getText().toString())
                    .addOnCompleteListener(new OnCompleteListener<Void>() {
                        @Override
                        public void onComplete(@NonNull Task<Void> task) {
                            DialogUtils.dismissProgressDialog();
                            if (task.isSuccessful()) {
                                Toast.makeText(ForgotPasswordActivity.this, "An email has been sent to you.", Toast.LENGTH_SHORT).show();
                                finish();
                            } else {
                                Toast.makeText(ForgotPasswordActivity.this, task.getException().getMessage(), Toast.LENGTH_SHORT).show();
                            }
                        }
                    });
        }
    }
    
    

    # Re-Authenticate Firebase user

    public class ReAuthenticateDialogFragment extends DialogFragment {
    
        @BindView(R.id.et_dialog_reauthenticate_email)
        EditText mEditTextEmail;
        @BindView(R.id.et_dialog_reauthenticate_password)
        EditText mEditTextPassword;
        private OnReauthenticateSuccessListener mOnReauthenticateSuccessListener;
    
        @OnClick(R.id.btn_dialog_reauthenticate)
        void onReauthenticateClick() {
    
            FormValidationUtils.clearErrors(mEditTextEmail, mEditTextPassword);
    
            if (FormValidationUtils.isBlank(mEditTextEmail)) {
                FormValidationUtils.setError(null, mEditTextEmail, "Please enter email");
                return;
            }
    
            if (!FormValidationUtils.isEmailValid(mEditTextEmail)) {
                FormValidationUtils.setError(null, mEditTextEmail, "Please enter valid email");
                return;
            }
    
            if (TextUtils.isEmpty(mEditTextPassword.getText())) {
                FormValidationUtils.setError(null, mEditTextPassword, "Please enter password");
                return;
            }
    
            reauthenticateUser(mEditTextEmail.getText().toString(), mEditTextPassword.getText().toString());
        }
    
        private void reauthenticateUser(String email, String password) {
            DialogUtils.showProgressDialog(getActivity(), "Re-Authenticating", "Please wait...", false);
            FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
            AuthCredential authCredential = EmailAuthProvider.getCredential(email, password);
            firebaseUser.reauthenticate(authCredential)
                    .addOnCompleteListener(new OnCompleteListener<Void>() {
                        @Override
                        public void onComplete(@NonNull Task<Void> task) {
                            DialogUtils.dismissProgressDialog();
                            if (task.isSuccessful()) {
                                mOnReauthenticateSuccessListener.onReauthenticateSuccess();
                                dismiss();
                            } else {
                                ((BaseAppCompatActivity) getActivity()).showToast(task.getException().getMessage());
                            }
                        }
                    });
        }
    
        @Override
        public void onAttach(Context context) {
            super.onAttach(context);
            mOnReauthenticateSuccessListener = (OnReauthenticateSuccessListener) context;
        }
    
        @OnClick(R.id.btn_dialog_reauthenticate_cancel)
        void onCancelClick() {
            dismiss();
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.dialog_reauthenticate, container);
            ButterKnife.bind(this, view);
            return view;
        }
    
        @Override
        public void onResume() {
            super.onResume();
            Window window = getDialog().getWindow();
            window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT);
        }
    
        interface OnReauthenticateSuccessListener {
            void onReauthenticateSuccess();
        }
    }
    
    

    # Firebase Storage Operations

    With this example, you will be able to perform following operations:

    1. Connect to Firebase Storage
    2. Create a directory named “images”
    3. Upload a file in images directory
    4. Download a file from images directory
    5. Delete a file from images directory
    public class MainActivity extends AppCompatActivity {
    
        private static final int REQUEST_CODE_PICK_IMAGE = 1;
        private static final int PERMISSION_READ_WRITE_EXTERNAL_STORAGE = 2;
    
        private FirebaseStorage mFirebaseStorage;
        private StorageReference mStorageReference;
        private StorageReference mStorageReferenceImages;
        private Uri mUri;
        private ImageView mImageView;
        private ProgressDialog mProgressDialog;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
            mImageView = (ImageView) findViewById(R.id.imageView);
            setSupportActionBar(toolbar);
    
            // Create an instance of Firebase Storage
            mFirebaseStorage = FirebaseStorage.getInstance();
        }
    
        private void pickImage() {
            Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            startActivityForResult(intent, REQUEST_CODE_PICK_IMAGE);
        }
    
        @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            if (resultCode == RESULT_OK) {
                if (requestCode == REQUEST_CODE_PICK_IMAGE) {
                    String filePath = FileUtil.getPath(this, data.getData());
                    mUri = Uri.fromFile(new File(filePath));
                    uploadFile(mUri);
                }
            }
        }
    
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            if (requestCode == PERMISSION_READ_WRITE_EXTERNAL_STORAGE) {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    pickImage();
                }
            }
        }
    
        private void showProgressDialog(String title, String message) {
            if (mProgressDialog != null && mProgressDialog.isShowing())
                mProgressDialog.setMessage(message);
            else
                mProgressDialog = ProgressDialog.show(this, title, message, true, false);
        }
    
        private void hideProgressDialog() {
            if (mProgressDialog != null && mProgressDialog.isShowing()) {
                mProgressDialog.dismiss();
            }
        }
    
        private void showToast(String message) {
            Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
        }
    
        public void showHorizontalProgressDialog(String title, String body) {
    
            if (mProgressDialog != null && mProgressDialog.isShowing()) {
                mProgressDialog.setTitle(title);
                mProgressDialog.setMessage(body);
            } else {
                mProgressDialog = new ProgressDialog(this);
                mProgressDialog.setTitle(title);
                mProgressDialog.setMessage(body);
                mProgressDialog.setIndeterminate(false);
                mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
                mProgressDialog.setProgress(0);
                mProgressDialog.setMax(100);
                mProgressDialog.setCancelable(false);
                mProgressDialog.show();
            }
        }
    
        public void updateProgress(int progress) {
            if (mProgressDialog != null && mProgressDialog.isShowing()) {
                mProgressDialog.setProgress(progress);
            }
        }
    
        /**
         * Step 1: Create a Storage
         *
         * @param view
         */
        public void onCreateReferenceClick(View view) {
            mStorageReference = mFirebaseStorage.getReferenceFromUrl("gs://**something**.appspot.com");
            showToast("Reference Created Successfully.");
            findViewById(R.id.button_step_2).setEnabled(true);
        }
    
        /**
         * Step 2: Create a directory named "Images"
         *
         * @param view
         */
        public void onCreateDirectoryClick(View view) {
            mStorageReferenceImages = mStorageReference.child("images");
            showToast("Directory 'images' created Successfully.");
            findViewById(R.id.button_step_3).setEnabled(true);
        }
    
        /**
         * Step 3: Upload an Image File and display it on ImageView
         *
         * @param view
         */
        public void onUploadFileClick(View view) {
            if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_READ_WRITE_EXTERNAL_STORAGE);
            else {
                pickImage();
            }
        }
    
        /**
         * Step 4: Download an Image File and display it on ImageView
         *
         * @param view
         */
        public void onDownloadFileClick(View view) {
            downloadFile(mUri);
        }
    
        /**
         * Step 5: Delete am Image File and remove Image from ImageView
         *
         * @param view
         */
        public void onDeleteFileClick(View view) {
            deleteFile(mUri);
        }
    
        private void showAlertDialog(Context ctx, String title, String body, DialogInterface.OnClickListener okListener) {
    
            if (okListener == null) {
                okListener = new DialogInterface.OnClickListener() {
    
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.cancel();
                    }
                };
            }
    
            AlertDialog.Builder builder = new AlertDialog.Builder(ctx).setMessage(body).setPositiveButton("OK", okListener).setCancelable(false);
    
            if (!TextUtils.isEmpty(title)) {
                builder.setTitle(title);
            }
    
            builder.show();
        }
    
        private void uploadFile(Uri uri) {
            mImageView.setImageResource(R.drawable.placeholder_image);
    
            StorageReference uploadStorageReference = mStorageReferenceImages.child(uri.getLastPathSegment());
            final UploadTask uploadTask = uploadStorageReference.putFile(uri);
            showHorizontalProgressDialog("Uploading", "Please wait...");
            uploadTask
                    .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                        @Override
                        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                            hideProgressDialog();
                            Uri downloadUrl = taskSnapshot.getDownloadUrl();
                            Log.d("MainActivity", downloadUrl.toString());
                            showAlertDialog(MainActivity.this, "Upload Complete", downloadUrl.toString(), new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                    findViewById(R.id.button_step_3).setEnabled(false);
                                    findViewById(R.id.button_step_4).setEnabled(true);
                                }
                            });
    
                            Glide.with(MainActivity.this)
                                    .load(downloadUrl)
                                    .into(mImageView);
                        }
                    })
                    .addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception exception) {
                            exception.printStackTrace();
                            // Handle unsuccessful uploads
                            hideProgressDialog();
                        }
                    })
                    .addOnProgressListener(MainActivity.this, new OnProgressListener<UploadTask.TaskSnapshot>() {
                        @Override
                        public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
                            int progress = (int) (100 * (float) taskSnapshot.getBytesTransferred() / taskSnapshot.getTotalByteCount());
                            Log.i("Progress", progress + "");
                            updateProgress(progress);
                        }
                    });
        }
    
        private void downloadFile(Uri uri) {
            mImageView.setImageResource(R.drawable.placeholder_image);
            final StorageReference storageReferenceImage = mStorageReferenceImages.child(uri.getLastPathSegment());
            File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
                    Environment.DIRECTORY_PICTURES), "Firebase Storage");
            if (!mediaStorageDir.exists()) {
                if (!mediaStorageDir.mkdirs()) {
                    Log.d("MainActivity", "failed to create Firebase Storage directory");
                }
            }
    
            final File localFile = new File(mediaStorageDir, uri.getLastPathSegment());
            try {
                localFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            showHorizontalProgressDialog("Downloading", "Please wait...");
            storageReferenceImage.getFile(localFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
                @Override
                public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
                    hideProgressDialog();
                    showAlertDialog(MainActivity.this, "Download Complete", localFile.getAbsolutePath(), new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            findViewById(R.id.button_step_4).setEnabled(false);
                            findViewById(R.id.button_step_5).setEnabled(true);
                        }
                    });
    
                    Glide.with(MainActivity.this)
                            .load(localFile)
                            .into(mImageView);
                }
            }).addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception exception) {
                    // Handle any errors
                    hideProgressDialog();
                    exception.printStackTrace();
                }
            }).addOnProgressListener(new OnProgressListener<FileDownloadTask.TaskSnapshot>() {
                @Override
                public void onProgress(FileDownloadTask.TaskSnapshot taskSnapshot) {
                    int progress = (int) (100 * (float) taskSnapshot.getBytesTransferred() / taskSnapshot.getTotalByteCount());
                    Log.i("Progress", progress + "");
                    updateProgress(progress);
                }
            });
        }
    
        private void deleteFile(Uri uri) {
            showProgressDialog("Deleting", "Please wait...");
            StorageReference storageReferenceImage = mStorageReferenceImages.child(uri.getLastPathSegment());
            storageReferenceImage.delete().addOnSuccessListener(new OnSuccessListener<Void>() {
                @Override
                public void onSuccess(Void aVoid) {
                    hideProgressDialog();
                    showAlertDialog(MainActivity.this, "Success", "File deleted successfully.", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            mImageView.setImageResource(R.drawable.placeholder_image);
                            findViewById(R.id.button_step_3).setEnabled(true);
                            findViewById(R.id.button_step_4).setEnabled(false);
                            findViewById(R.id.button_step_5).setEnabled(false);
                        }
                    });
                    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
                            Environment.DIRECTORY_PICTURES), "Firebase Storage");
                    if (!mediaStorageDir.exists()) {
                        if (!mediaStorageDir.mkdirs()) {
                            Log.d("MainActivity", "failed to create Firebase Storage directory");
                        }
                    }
                    deleteFiles(mediaStorageDir);
                }
            }).addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception exception) {
                    hideProgressDialog();
                    exception.printStackTrace();
                }
            });
        }
    
        private void deleteFiles(File directory) {
            if (directory.isDirectory())
                for (File child : directory.listFiles())
                    child.delete();
        }
    }
    
    

    By default, Firebase Storage rules applies Authentication restriction. If user is authenticated, only then, he can perform operations on Firebase Storage, else he cannot. I have disabled the authentication part in this demo by updating Storage rules. Previously, rules were looking like:

    
    service firebase.storage {
       match /b/**something**.appspot.com/o {
         match /{allPaths=**} {
           allow read, write: if request.auth != null;
         }
       }
     }
    
    

    But I changed to skip the authentication:

    service firebase.storage {
      match /b/**something**.appspot.com/o {
        match /{allPaths=**} {
          allow read, write;
        }
      }
    }
    
    

    # Firebase Realtime Database: how to set/get data

    Note: Let's setup some anonymous authentication for the example

    {
      "rules": {
        ".read": "auth != null",
        ".write": "auth != null"
      }
    }
    
    

    Once it is done, create a child by editing your database address. For example:

    https://your-project.firebaseio.com/ to https://your-project.firebaseio.com/chat

    We will put data to this location from our Android device. You don't have to create the database structure (tabs, fields... etc), it will be automatically created when you'll send Java object to Firebase!

    Create a Java object that contains all the attributes you want to send to the database:

    public class ChatMessage {
        private String username;
        private String message;
    
        public ChatMessage(String username, String message) {
            this.username = username;
            this.message = message;
        }
    
        public ChatMessage() {} // you MUST have an empty constructor
    
        public String getUsername() {
            return username;
        }
    
        public String getMessage() {
            return message;
        }
    }
    
    

    Then in your activity:

    if (FirebaseAuth.getInstance().getCurrentUser() == null) {
            FirebaseAuth.getInstance().signInAnonymously().addOnCompleteListener(new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isComplete() && task.isSuccessful()){
                        FirebaseDatabase database = FirebaseDatabase.getInstance();
                        DatabaseReference reference = database.getReference("chat"); // reference is 'chat' because we created the database at /chat
                    }
                }
            });
    }
    
    

    To send a value:

    ChatMessage msg = new ChatMessage("user1", "Hello World!");
    reference.push().setValue(msg);
    
    

    To receive changes that occurs in the database:

    reference.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            ChatMessage msg = dataSnapshot.getValue(ChatMessage.class);
            Log.d(TAG, msg.getUsername()+" "+msg.getMessage());
        }
    
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {}
        public void onChildRemoved(DataSnapshot dataSnapshot) {}
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {}
        public void onCancelled(DatabaseError databaseError) {}
    });
    
    

    enter image description here

    # Demo of FCM based notifications

    This example shows how to use the Firebase Cloud Messaging(FCM) platform. FCM is a successor of Google Cloud Messaging(GCM). It does not require C2D_MESSAGE permissions from the app users.

    Steps to integrate FCM are as follows.

  • Create sample hello world project in Android Studio Your Android studio screen would look like the following picture. [Demo Project screen with basic activity in Android Studio](https://i.stack.imgur.com/3k33n.png)

  • Next step is to set up firebase project. Visit [https://console.firebase.google.com](https://console.firebase.google.com) and create a project with an identical name, so that you can track it easily.[enter image description here](https://i.stack.imgur.com/sK4vn.png)
  • Now it is time to add firebase to your sample android project you have just created. You will need package name of your project and Debug signing certificate SHA-1(optional). a. Package name - It can be found from the android manifest XML file. b. Debug signing SHA-1 certificate - It can be found by running following command in the terminal.
  • keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android

    Enter this information in the firebase console and add the app to firebase project. Once you click on add app button, your browser would automatically download a JSON file named "google-services.json".

  • Now copy the google-services.json file you have just downloaded into your Android app module root directory.[enter image description here](https://i.stack.imgur.com/ih9DF.png)
  • Follow the instructions given on the firebase console as you proceed ahead. a. Add following code line to your project level build.gradle

    `dependencies{ classpath 'com.google.gms:google-services:3.1.0' .....` b. Add following code line at the end of your app level build.gradle.
        //following are the dependencies to be added
        compile 'com.google.firebase:firebase-messaging:11.0.4'
        compile 'com.android.support:multidex:1.0.1'
    }
    // this line goes to the end of the file
    apply plugin: 'com.google.gms.google-services'
    
    

    c. Android studio would ask you to sync project. Click on Sync now.

  • Next task is to add two services. a. One extending FirebaseMessagingService with intent-filter as following

        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT"/>
        </intent-filter>
    
    

    b. One extending FirebaseInstanceIDService.

    <intent-filter>
        <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
    </intent-filter>
    
    
  • FirebaseMessagingService code should look like this.
    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;
    
    import com.google.firebase.messaging.FirebaseMessagingService;
    
    public class MyFirebaseMessagingService extends FirebaseMessagingService {
        public MyFirebaseMessagingService() {
        }
    }
    
    
  • FirebaseInstanceIdService should look like this.
    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;
    
    import com.google.firebase.iid.FirebaseInstanceIdService;
    
    public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
        public MyFirebaseInstanceIDService() {
        }
    }
    
    
  • Now it is time to capture the device registration token. Add following line of code to MainActivity's onCreate method.
    String token = FirebaseInstanceId.getInstance().getToken();
    Log.d("FCMAPP", "Token is "+token);
    
    
  • Once we have the access token, we can use firebase console to send out the notification. Run the app on your android handset. [Firebase Console Notification](https://i.stack.imgur.com/Rn47F.png)
  • Click on Notification in Firebase console and UI will help you to send out your first message. Firebase offers functionality to send messages to single device(By using the device token id we captured) or all the users using our app or to specific group of users. Once you send your first message, your mobile screen should look like following.

    Notification

    Thank you

    # Firebase Sign Out

    Initialization of variable

    private GoogleApiClient mGoogleApiClient;
    
    

    You must have to Write this Code in onCreate() method of all that when u put signout button.

    
    mGoogleApiClient = new GoogleApiClient.Builder(this)
                .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
                .addApi(Auth.GOOGLE_SIGN_IN_API)
                .build();
    
    

    Put below code on signout button.

    Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
                        new ResultCallback<Status>() {
                            @Override
                            public void onResult(Status status) {
                                FirebaseAuth.getInstance().signOut();
                                Intent i1 = new Intent(MainActivity.this, GoogleSignInActivity.class);
                                startActivity(i1);
                                Toast.makeText(MainActivity.this, "Logout Successfully!", Toast.LENGTH_SHORT).show();
                            }
                        });
    
    

    # Remarks

    # Firebase - Extended documentation:

    There is another tag where you can find more topics and examples about the use of Firebase.