Try using Firebase Cloud Functions on Android (Java)

I'm new to Android I tried to do Hello World using httpsCallable of Firebase Cloud Functions, so I will summarize the procedure.

1. Create an Android project

Assuming that the Android SDK itself is already installed, first start Android Studio and create a project.

Select File NewCreate New Project

For the template, select ʻEmpty Activity (if you like) and enter Name, Package name, Save location. Language selects Java`.

2. Preparing the Firebase SDK

Open your Firebase project (create it if you haven't already) in your browser and add your Android app. Test_Project_–_設定_–_Firebase_console.png From here, the tutorial screen will be displayed, so we will introduce it as it is. On the first page, first enter the package name that was set in Android Studio earlier, and enter any optional items. Download the second page, google-services.json, and go directly to the / app directory of your Android project. On the 3rd page, first edit the build settings of build.gradle in the project root.

build.gradle


// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        google()
        jcenter()
        
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.5.3'
        
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
        classpath 'com.google.gms:google-services:4.3.3'
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

Confirm that there are google () in two places, and it is instructed to add the dependent module (com.google.gms: google-services).

Another, edit build.gradle for each app.

app/build.gradle


apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.2"
    defaultConfig {
        applicationId "com.example.firebaseexample"
        minSdkVersion 16
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    //implementation 'com.google.firebase:firebase-core:17.2.2' //Add when using Analytics etc.
    implementation 'com.google.firebase:firebase-functions:19.0.1'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}

Add the second line ʻapply plugin:'com.google.gms.google-services'and add the required dependent packages. Click here for a list of packages (https://firebase.google.com/docs/reference/android/packages). Since we are only using Cloud Functions this time, we are adding onlycom.google.firebase: firebase-functions. In the above source, each version has been changed to the latest version. For Firebase support, minSdkVersion` should be 16 or higher. In other words, Android 4.1 is the lower limit for using the current Firebase SDK.

It seems that these steps can be done by opening the Assistant window from Tools Firebase of Android Studio, but this is all. So it didn't feel so convenient ...

After this, if Sync passes with File Sync Project with Gradle Files, the SDK installation is complete.

3. Create app screen

Screenshot (Jan 31, 2020 7_47_28 PM).png

Like this, let's create a screen that sends the entered text to Cloud Functions and displays the return value.

app/src/main/res/layout/activity_main.xml


<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <RelativeLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:gravity="center"
            android:layout_centerVertical="true">
            <TextView
                android:id="@+id/title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/title" />
            <EditText
                android:id="@+id/name"
                android:layout_width="200dp"
                android:layout_height="wrap_content"
                android:layout_marginTop="32dp"
                android:singleLine="true"/>
            <Button
                android:id="@+id/ok_button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="32dp"
                android:text="@string/ok_button"
                android:textColor="@color/colorWhite"
                android:background="@color/colorAccent"
                />
            <TextView
                android:id="@+id/result"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="32dp"
                android:text=""/>
        </LinearLayout>
    </RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

Edit the resources used on the screen.

app/src/main/res/values/colors.xml


<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#051E34</color>
    <color name="colorPrimaryDark">#051E34</color>
    <color name="colorAccent">#1A73E8</color>
    <color name="colorWhite">#FFFFFF</color>
</resources>

app/src/main/res/values/strings.xml


<resources>
    <string name="app_name">FirebaseExample</string>
    <string name="title">Enter your name!</string>
    <string name="ok_button">OK</string>
</resources>

4. Implement the process

First, add Internet access permission (before <application>) to the manifest. It seems to work without adding this, but just in case.

app/src/main/AndroidManifest.xml (part)


<uses-permission android:name="android.permission.INTERNET" />

Add processing to MainActivity.

java:app/src/main/java/.../MainActivity


package com.example.firebaseexample;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.google.android.gms.tasks.Continuation;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.functions.FirebaseFunctions;
import com.google.firebase.functions.FirebaseFunctionsException;
import com.google.firebase.functions.HttpsCallableResult;

import java.util.HashMap;
import java.util.Map;

public class MainActivity extends AppCompatActivity {
    private FirebaseFunctions mFunctions;
    private EditText nameInput;
    private TextView resultTextView;

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

        //Get Cloud Functions Client
        mFunctions = FirebaseFunctions.getInstance();

        //Get screen elements
        resultTextView = findViewById(R.id.result);
        nameInput = findViewById(R.id.name);

        //Set button click event listener
        final Button okButton = findViewById(R.id.ok_button);
        okButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                final String name = nameInput.getText().toString();
                helloWorld(name);
                hideInput(view);
            }
        });

        //Processing to close the keyboard when tapping the screen
        final View container = findViewById(R.id.container);
        container.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                hideInput(view);
            }
        });
    }

    /**
     *Close keyboard
     * @param view Clicked view
     */
    private void hideInput(@NonNull View view) {
        InputMethodManager inputMethodManager = (InputMethodManager)
                view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
        if (inputMethodManager != null) {
            inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(),0);
        }
    }

    /**
     *Hit a Cloud Functions function
     * @param name name
     * @return task
     */
    private Task helloWorld(String name) {
        //Create data to send
        Map<String, Object> data = new HashMap<>();
        data.put("name", name);
        
        //call helloWorld function
        return mFunctions
                .getHttpsCallable("helloWorld")
                .call(data)
                .continueWith(new Continuation<HttpsCallableResult, String>() {
                    @Override
                    public String then(@NonNull Task<HttpsCallableResult> task) {
                        String result = (String) task.getResult().getData();
                        return result;
                    }
                })
                .addOnCompleteListener(new OnCompleteListener<String>() {
                    @Override
                    public void onComplete(@NonNull Task<String> task) {
                        if (!task.isSuccessful()) { //On error
                            Exception e = task.getException();
                            if (e instanceof FirebaseFunctionsException) {
                                //Output the details of the error to the log
                                FirebaseFunctionsException ffe = (FirebaseFunctionsException) e;
                                FirebaseFunctionsException.Code code = ffe.getCode();
                                Object details = ffe.getDetails();
                                Log.e("functions error", code.toString());
                                Log.e("functions error", String.valueOf(details));
                            }
                        } else {
                            String result = task.getResult();
                            if (result != null) {
                                resultTextView.setText(result); //Set the return value on the screen
                            }
                        }
                    }
                });
    }
}

I'm not used to asynchronous processing in Java, so it may seem confusing, but basically, if I followed this tutorial, I could use Functions smoothly.

** Call a function from the app | Firebase ** (select Java Android tab) https://firebase.google.com/docs/functions/callable

5. Add function

The implementation and deployment of functions is the same as when used on the Web. If you have not installed Firebase CLI globally, install it as follows.

$ npm install -g firebase-tools

Initialize in any directory (even in the project directory).

$ firebase init

After logging in to your account and selecting a project, an input screen for selecting the function to use will appear. Select Functions (space key) here.

? Which Firebase CLI features do you want to set up for this folder? Press Space
 to select features, then Enter to confirm your choices. (Press <space> to selec
t, <a> to toggle all, <i> to invert selection)
 ◯ Database: Deploy Firebase Realtime Database Rules
 ◯ Firestore: Deploy rules and create indexes for Firestore
❯◯ Functions: Configure and deploy Cloud Functions
 ◯ Hosting: Configure and deploy Firebase Hosting sites
 ◯ Storage: Deploy Cloud Storage security rules
 ◯ Emulators: Set up local emulators for Firebase features

Once the functions directory is created, add and deploy a function that simply returns a string like this.

functions/index.js


const functions = require('firebase-functions');

exports.helloWorld = functions.https.onCall((data, context) => {
  return `Hello ${data.name}`;
});
$ firebase deploy --only functions

6. Run

If you connect your Android device with USB and Run,

Screenshot (Jan 31, 2020 8_20_58 PM).png I was able to confirm that `httpsCallable` can be used without any problem and the return value is displayed.

Recommended Posts

Try using Firebase Cloud Functions on Android (Java)
Try communication using gRPC on Android + Java server
Try image classification using TensorFlow Lite on Android (JAVA)
Try using the service on Android Oreo
Sobel filter using OpenCV on Android (Java)
Try using GCP's Cloud Vision API in Java
[Android] [Java] Download images on GCS (Google Cloud Storage) with Stream using Glide
I tried using "nifty cloud mobile backend" and "Firebase" Authentication on Kotlin + Android
Try using RocksDB in Java
Try scraping using java [Notes]
Try Hello World using plain Java on a Docker container
Using Java on OSX 10.15 (Catalina) β
Try implementing Android Hilt in Java
Try using Redmine on Mac docker
Try Quarkus on IBM Cloud Shell
Try using Redis with Java (jar)
Use Java 11 with Google Cloud Functions
Save ArrayList using GSON on Android
[Java] Try to implement using generics
Try using IBM Java method tracing
Notes on Android (java) thread processing
Try using Hyperledger Iroha's Java SDK
[Java] Where did you try using java?
Try using the two-point measurement function of Firebase Performance Monitoring. [Android]
Try using Java framework Nablarch [Web application]
Try using the Stream API in Java
Using JupyterLab + Java with WSL on Windows 10
Calling java from C ++ on Android NDK
Notes on operators using Java ~ String type ~
Study Java Try using Scanner or Map
Try using JSON format API in Java
Build Java 8 development environment on AWS Cloud9
Deploy Java programs on SAP Cloud Platform
Try using JobScheduler's REST-API --Java RestClient implementation--
Try using the Emotion API from Android
Try using the Wii remote with Java
Create Java applications with IBM Cloud Functions
Try using JobScheduler's REST-API --Java RestClient Test class-
Try to build Java8 environment on Amazon Linux2
Install java and android-sdk on Mac using homebrew
Android application development using Unity + ARCore on Ubuntu
Try Azure Service Fabric (Java) on Mac-Local Environment
Beginners try using android studio Part 2 (event processing)
Try local file search using Fess on CentOS7
Try local file search using Fess on CentOS8
Try using Sourcetrail (win version) in Java code
Try using Sourcetrail (macOS version) in Java code
Beginners try using android studio Part 1 (Hello World)
Try similar search of Image Search using Java SDK [Search]
(Android) Try to display static text using DataBinding
Try accessing the dataset from Java using JZOS
Translator using Microsoft Translator Text API on Android ~ Implementation ~
[Java] 4 steps to implement splash screen on Android
Try using the COTOHA API parsing in Java
Story of test automation using Appium [Android / java]
Try using libGDX
Try using Maven
Try using powermock-mockito2-2.0.2
Try using GraalVM
Try Java 8 Stream
Try using jmockit 1.48