When developing your enterprise mobile app that needs centralized hosting of data, use of cloud-native services such as Cloudant No-SQL Database for storing textual data and Object Storage service for storing image/video/audio data, allows you to quickly go from idea-conception to reality. The Mobile Foundation service available from IBM Cloud provides a scalable mobile access gateway for securely accessing those backend services, and it provides other essential mobile backend capabilities such as push notifications, app lifecycle management and app analytics.
This code pattern gives you step by step instructions for developing an Ionic/Cordova based hybrid mobile app that securely connects to Cloudant and Object Storage services via IBM MobileFoundation (aka MFP) service.
When you have completed this pattern, you will understand:
imgcache.js
in Ionic app for caching images fetched from Cloud Object Storage service.Login
.Authorization=<value returned from MFP adapter>
while fetching images. Mobile app displays the data obtained from MFP adapter as a list of items. The image caching plugin running on the mobile app downloads and caches images from Cloud Object Storage.+
button to report a new civic problem. A new page is shown where user can enter a description for the new civic problem as well as capture image and geo-location of the problem spot. User clicks on Submit
button.Install Node.js
by downloading the setup from https://nodejs.org/en/ (Node.js 8.x or above)
$ node --version
v8.6.0
Install Cordova
$ sudo npm install -g cordova@7.0.1
$ cordova --version
7.0.1
Note: If you are on Windows, instead of using sudo
, run the above command (and the ones below) in a command prompt opened in administrative mode.
Note: Please refer MFP documentation for compatible versions of Cordova - https://mobilefirstplatform.ibmcloud.com/tutorials/en/foundation/8.0/application-development/sdk/cordova/
Install Ionic
$ sudo npm install -g ionic@3.19.0
$ ionic --version
3.19.0
Install IBM MobileFirst Platform CLI
$ sudo npm install -g mfpdev-cli
$ mfpdev --version
8.0.0-2017091111
Note: While installing MFP CLI, if you hit an error saying npm ERR! package.json npm can't find a package.json file in your current directory.
, then it is most likely due to MFP CLI not being supported in your npm version. In such a case, downgrade your npm as below, and then install MFP CLI.
$ sudo npm install -g npm@3.10.10
Install GIT https://git-scm.com/downloads
$ git --version
git version 2.9.3 ...
Install Maven:
On Mac, you can use brew install
for installing Maven as shown below:
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
$ brew install maven
$ mvn --version
Apache Maven 3.5.0 ...
Install Java SDK from https://www.oracle.com/technetwork/java/javase/downloads/index.html
$ java -version
java version "1.8.0_101"
Install an IDE for TypeScript such as Atom on Mac.
After installing Atom, install TypeScript plugin for Atom as shown below.
apm install atom-typescript
Databases
.Create Database
. Specify name of database as myward
as shown below. Click Create
.Once the database is created, the dashboard will update to show the documents inside myward
database (which, as expected, will be empty to begin with).
Create Document
. Under document content, after the auto populated _id
field, enter grievance details as shown below. Please note that you need to put a comma (,) after the auto populated _id
field.
{
"_id": "7fc63023799dfda9582609e75127b4fa",
"reportedBy": "shivahr@gmail.com",
"reportedDateTime": "20171125_152627",
"picture": {
"large": "IMG-20171125-WA0012.jpeg",
"thumbnail": "thumbnail_IMG-20171125-WA0012.jpg"
},
"problemDescription": "Car parking on busy market road chocking movement of other vehicles and pedestrians",
"geoLocation": {
"type": "Point",
"coordinates": [
77.7893168,
13.0773568
]
},
"address": "Basaveshwara Temple road (behind Market Road), Hosakote, Bangalore 562114"
}
Click Create Document
to create/save the document.
The myward
database should now list the six documents as shown below under Table
view.
myward
database, click on Permissions
and then click on Generate API Key
as shown in the snapshot below.The newly added key would get listed under Cloudant users with default permission of reader only. Select the checkbox under writer next to the new key to give it write permission as well.
In the IBM Cloud Dashboard, click on Catalog
and select Object Storage service under Infrastructure
-> Storage
. Click on Create
as shown below.
The IBM Cloud Object Storage dashboard will get shown. In the Buckets and objects
page, click on Create bucket
. Give a unique name for the bucket. Leave the default selections as-is for Resiliency (Cross Region
), Location (us-geo
) and Storage class (Standard
), and click on Create
as shown below.
The Bucket overview page for the newly created bucket will get shown. Click on Add objects
. In Upload obects
dialog, click on Add files
and select all the images under SampleData directory (the six images and their thumbnails). Click Open
. Click on Upload
as shown below. Once upload is complete, you should see the images listed under your bucket.
Create Service ID
Identity & Access
(on the left side of the page), select Service IDs
and click Create
. Give a name and description, and click Create
.Add Cloud Object Storage Writer role to that service ID
Bucket permissions
under Buckets and objects
.Service IDs
tab. Under Select a service ID
, select the service ID created in the above step. Under Assign a role to this service ID for this bucket
, select Writer
. Click Create policy
as shown below. You should get a confirmation dialog saying “Service permission created“.Create API Key
Service IDs
, click on the service ID created earlier.
Under Access policies
, you should see the Writer
role for your bucket.API keys
tab and then click on Create
button. In the Create API key
dialog, give a name and description for the API key and click on Create
. You should get a confirmation dialog saying API key successfully created
as shown below.Download
and save the API key as shown below. Note: This is the only time you will see the key. You cannot retrieve it later.Close
.In the IBM Cloud Dashboard, click on Catalog
and select Mobile Foundation service under Platform
-> Mobile
. Click on Create
as shown below.
Note: If Mobile Foundation service is not available with your current account type, then you can either:
In the Mobile Foundation service overview page that gets shown, click on Service credentials
. Expand View credentials
and make a note of the url
, user
and password
as shown below.
Note: If you are using the MobileFirst Developer Kit, the default url would be http://localhost:9080 and username/password would be admin/admin .
Back on your local machine, configure MFP CLI to work with Mobile Foundation server by running the following command in console.
Note: For Enter the fully qualified URL of this server:
, enter the url
mentioned in credentials followed by :443
(the default HTTPS port). If you are using the MobileFirst Developer Kit, then enter http://localhost:9080 .
$ mfpdev server add
? Enter the name of the new server profile: Cloud-MFP
? Enter the fully qualified URL of this server: https://mobilefoundation-71-hb-server.mybluemix.net:443
? Enter the MobileFirst Server administrator login ID: admin
? Enter the MobileFirst Server administrator password: **********
? Save the administrator password for this server?: Yes
? Enter the context root of the MobileFirst administration services: mfpadmin
? Enter the MobileFirst Server connection timeout in seconds: 30
? Make this server the default?: Yes
Verifying server configuration...
The following runtimes are currently installed on this server: mfp
Server profile 'Cloud-MFP' added successfully.
$ mfpdev server info
Name URL
--------------------------------------------------------------------------------------
Cloud-MFP https://mobilefoundation-71-hb-server.mybluemix.net:443 [Default]
--------------------------------------------------------------------------------------
$ git clone https://github.com/IBM/Ionic-MFP-App
$ cd Ionic-MFP-App
Update IonicMobileApp/config.xml
as below. Change id
, name
, description
and author
details appropriately.
<?xml version='1.0' encoding='utf-8'?>
<widget id="org.mycity.myward" version="0.0.1" xmlns="https://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0" xmlns:mfp="http://www.ibm.com/mobilefirst/cordova-plugin-mfp">
<name>MyWard</name>
<description>Get your civic issues resolved by posting through this app.</description>
<author email="shivahr@gmail.com" href="https://developer.ibm.com/code/author/shivahr/">Shiva Kumar H R</author>
...
Open MobileFoundationAdapters/MyWardData/src/main/adapter-resources/adapter.xml
and update the following properties to point to the Cloudant database created in Step 2.
key
and password
with the Cloudant API key as generated in Step 2.2.account
, specify the Cloudant Dashboard URL portion upto (and including) -bluemix.cloudant.com as shown in the snapshot of Step 2.2.DBName
, leave the default value of myward
as-is.
<mfp:adapter name="MyWardData" ...>
<property name="account" displayName="Cloudant account" defaultValue="" />
<property name="key" displayName="Cloudant key" defaultValue="" />
<property name="password" displayName="Cloudant password" defaultValue="" />
<property name="DBName" displayName="Cloudant DB name" defaultValue="myward" />
...
</mfp:adapter>
Open MobileFoundationAdapters/MyWardData/src/main/adapter-resources/adapter.xml
and update the following properties to point to the Cloud Object Storage created in Step 3.
bucketName
as created in Step 3.1.serviceId
and apiKey
created in Step 3.2.endpointURL
as per the specification in https://cloud.ibm.com/docs/services/cloud-object-storage/basics/endpoints.html#select-regions-and-endpoints.
<mfp:adapter name="MyWardData" ...>
...
<property name="endpointURL" displayName="Cloud Object Storage Endpoint Public URL" defaultValue="https://s3-api.us-geo.objectstorage.softlayer.net" />
<property name="bucketName" displayName="Cloud Object Storage Bucket Name" defaultValue="" />
<property name="serviceId" displayName="Cloud Object Storage Service ID" defaultValue="" />
<property name="apiKey" displayName="Cloud Object Storage API Key" defaultValue="" />
</mfp:adapter>
Build and deploy UserLogin
adapter as below.
$ cd MobileFoundationAdapters/
$ cd UserLogin
$ mfpdev adapter build
$ mfpdev adapter deploy
Note: In Step 4, if you specified No
to Make this server the default?
, then you need to specify the name of your server profile (Cloud-MFP
in our case) at the end of mfpdev adapter deploy
command as shown below.
$ mfpdev adapter deploy Cloud-MFP
Build and deploy MyWardData
adapter as below.
$ cd ../MyWardData/
$ mfpdev adapter build
$ mfpdev adapter deploy
Launch MFP Dashboard as below:
Cloud Foundry Services
, click on the Mobile Foundation
service you created in Step 4. The service overview page that gets shown, will have the MFP dashboard embedded within it. You can also open the MFP dashboard in a separate browser tab by appending /mfpconsole
to the url mentioned in Step 4.MyWardData
and UserLogin
adapters listed.Verify MFP Adapter configuration as below:
Inside the MFP dashboard, click on the MyWardData
adapter. Under Configurations
tab, you should see the various properties we specified in Step 5.3 and Step 5.4 for accessing Cloudant database and Cloud Object Storage as shown below. As an alternative to specifying those property values in MobileFoundationAdapters/MyWardData/src/main/adapter-resources/adapter.xml
as previously shown in Step 5.3 and Step 5.4, you can deploy the adapters with empty defaultValue
, and once the adapter is deployed, change the values on this page.
Click on Resources
tab. You should see the various REST APIs exposed by MyWardData
adapter as shown below. The Security
column should show the protecting scope UserLogin
against each REST method.
Create temporary credentials to test adapter REST API as below:
Runtime Settings
. Click on Confidential Clients
. Then click on New
.In the form that pops up, specify values for ID
and Secret
as shown in snapshot below. For Allowed Scope
enter **
and click on Add
. Finally click on Save
.
Test adapter REST API as below:
Inside the MFP dashboard, click on the MyWardData
adapter. Click on Resources
and then click on View Swagger Docs
. The Swagger UI for adapter REST APIs will get shown in a new window/tab.
Inside the Swagger UI, click on Expand Operations
.
To test the GET /
API, first click on OFF
toggle button to enable authentication. Select Default Scope
and click on Authorize
as shown below. Enter the ID
and Secret
created above against Username
and Password
. Click OK
. If authentication is successful, the toggle button will switch to ON
position.
Now click on Try it out
button to run the GET /
API. The API response should get shown in the Response Body
as shown in snapshot below.
The GET API on /objectStorage
should return a JSON object containing baseUrl
and authorizationHeader
as shown below.
Delete the temporary credentials after testing adapter REST API as below:
Runtime Settings
. Click on Confidential Clients
.Client ID
created previously.Configure
-> SDK Manager
Android SDK Location
.SDK Platforms
, select Android 6.0 (Marshmallow) API Level 23
or higher. Click Apply
and then click OK
. This will install Android SDK Platform on your machine.IonicMobileApp/config.xml
and specify the API level in android-targetSdkVersion
as shown below.
<preference name="android-minSdkVersion" value="16" />
<preference name="android-targetSdkVersion" value="23" />
### 7.2 Enable developer options and USB debugging on your Android phone
* Enable USB debugging on your Android phone as per the steps in https://developer.android.com/studio/debug/dev-options
- Launch the Settings app on your phone. Select `About Device` -> `Software Info`. Tap `Build number` 7 times to enable developer options.
- Return to Settings list. Select `Developer options` and enable `USB debugging`.
* If you are developing on Windows, then you need to install the appropriate USB driver as per instructions in https://developer.android.com/studio/run/oem-usb.
* Connect the Android phone to your development machine by USB cable, and accept `allow` access on your phone.
### 7.3 Setup API keys for using Google Maps
* Get an API key for using the Google Maps Android API as per instructions in https://developers.google.com/maps/documentation/android-sdk/signup.
You can similarly get an API key for using the Google Maps SDK for iOS as per instructions in
https://developers.google.com/maps/documentation/ios-sdk/get-api-key.
* Add the Google Maps API keys into the `MyWard` app as below:
```
$ cd ../../IonicMobileApp/
$ ionic cordova plugin add cordova-plugin-googlemaps --variable API_KEY_FOR_ANDROID="