Make and receive phone calls in Android apps with Nexmo In-App Voice and Firebase

Published July 03, 2018 by Chris Guzman

With Nexmo In-App Voice, you can easily make and receive phone calls with the Nexmo Stitch Android SDK and WebRTC technology. In this tutorial we’ll show you how to make a simple Android app that can make outbound phone calls and receive incoming phone calls. This functionality could be used where customers want to make and receive calls to customer service, without leaving the app.

To get the app up and running, we’ll use Firebase Functions to host the NCCO and return a JWT for users to login with.

To follow along with this blog post, you should have some knowledge of JavaScript and be able to build an Android app using Kotlin.

Before we get started

There are a few things you’ll need before we get started.

  1. Nexmo Account
  2. Firebase Account

Set up the Firebase Function.

First, we’ll want to create a new directory for our Firebase functions project and to store our config files.

Now that a new directory has been made, we can follow the for setup instructions provided by Firebase and create a new project.

For this project I chose to use JavaScript instead of TypeScript.

If like me, you were not able to create a firebase function project from the command line you can visit the Firebase Console to create a new project, then run firebase use --add from your command line.

Edit the Firebase Functions

You can see the final version of the methods we’ll use for the Firebase Functions in the repo for this demo on GitHub. In short we need three endpoints:

  1. An Answer URL that will host the NCCO
  2. An Event URL to capture events from the Voice API
  3. A URL to return a JWT for users to login with

To edit the Firebase functions, we’ll need to edit the index.js file in the new functions/ directory that firebase created after we ran firebase init functions

Let’s start by taking a look at the Answer method

Since Nexmo’s Voice API uses one answer URL per application, we can dynamically show the NCCO for accepting an inbound call if the to query parameter is null. If the to query parameter is not null, then we’ll show the NCCO for making an outbound phone call.

Our endpoint for providing a JWT for users is fairly straightforward. We’ll use the Nexmo Node library to generate a JWT. In order to use the library we’ll need to install the package.

After installing the library, you can ensure everything is working correctly by inspecting the package.json file. It should look like so:

Once the Nexmo Node library is installed, we can use it in the jwt endpoint like so to return a valid user_jwt.

Now that we’ve created our Firebase functions, we will create a Nexmo application.

Deploy the Firebase function

Now that the Firebase Functions have been written, we can deploy the Firebase project. After deploying the Functions, Firebase will give us the URLs for our answer and event endpoints. We can use these URLs to create our Nexmo application.

Set up the Nexmo Application.

To create an application, we’ll use the answer and event url that Firebase provided us in the previous section.

Note: I’m saving the private key in the functions/ directory so that the file can be referenced when the function is published

Record the application ID and save the private key in the “functions” directory. I recommend you add the private.key and .nexmo-app files with your credentials to your .gitignore.

Following best practices, we’ll store some environment variables Firebase config via the firebase CLI. The Firebase docs contain an overview about environment configuration.

Now we need to store the Nexmo application ID in the firebase config via the firebase CLI.

Note: Firebase requires config variable keys to be lowercase, so we’ll use snake case for our variable names.

If you wish, you could upload the private key string found in the .nexmo-app file from your Nexmo application as a firebase config variable instead of uploading the entire private.key file to the firebase functions.

Link a phone number and user to our application

Now that our functions have been written, we need to buy a number so that our users can make outbound calls from that number and receive inbound calls in their Android app whenever someone dials that number. After the number is bought we’ll link the number to the Nexmo application and set it as the from_number in the Firebase Config variables.

Nexmo In-App Voice also requires us to create a user for authentication. By creating a user, we can route incoming phone calls to them. We can do that simply with the beta version of the Nexmo CLI

Set up the Android project

If you’d like to view the finished project for our Android app you can view the source code on GitHub.

First we need to add the necessary libraries. We’re going to use the Nexmo Stitch Android SDK, Retrofit, and Retrofit’s Moshi Converter.

We’ll use Retrofit to make a GET request the Firebase function’s JWT endpoint that Firebase CLI provided us.

Add the Login Activity

Having set up Retrofit, we can use it to retrieve a JWT from the JWT Firebase function endpoint in the LoginActivity. Here I’ll show the happy path when we retrieve the user JWT and use it to login to the Nexmo Stitch Android SDK. The layout for this Activity is available in GitHub.

Add the Call Activity

We’ll add a simple layout for inputting phone numbers, starting, and ending phone calls. The layout for this Activity is available in GitHub.
Like before I’ll show the happy path of making and receiving a call.

As you can see the Nexmo Stitch SDK handles the hard work of placing and answering phone calls.

How does it work?

Receive a Phone Call

When a user makes a phone call to the number we bought in the previous section, Nexmo will look up the NCCO in our Answer URL at https://your-project-name.cloudfunctions.net/answer. The NCCO will look like this:

This NCCO will direct the call to the “Customer” user we created in our app with the Stitch SDK. The app will handle answering the call by attaching the Call Listener in attachIncomingCallListener() For the sake of simplicity, we’ll automatically answer the call, but you could implement a UI and logic to allow the user to answer or reject() the call.

Make a Phone Call

If the user choose to make a call, we’ll handle that in the callPhone() method. For example if our method was called like so:

Then the client.callPhone(phoneNumber, callback) method in the Nexmo Stitch Android SDK will use the Stitch API to make GET a request to your answer url https://your-project-name.cloudfunctions.net/answer with the following query parameters:

We can use the to parameter to dynamically return a NCCO that tells Nexmo which phone number to call. The Stitch API will see the following NCCO response:

In this case, the from number is the number that we rented from Nexmo and set as the nexmo.from_number with Firebase config variables. The value in number key in the endpoint array is the number that our user wants to call.

Try it for yourself

The repo for this sample project contains the source code for both the Firebase Functions and the Android Sample app. Clone the project for yourself to check it out!

What’s next?

Now that you’ve learned how to make and receive phone calls with Nexmo In-App Voice you can also learn more about In-App Messaging.

For more in depth details of what the Nexmo Stitch Android SDK covers, you can read the SDK documentation online.

Our Voice API also offers other possibilities beyond just connecting and receiving calls! Visit our documentation to learn more about recording calls, playing audio stream to calls, and more.

Leave a Reply

Your email address will not be published.