frollo-android-sdk

Overview

Introduction

The Frollo Android SDK is designed to simplify integration of the Frollo APIs by providing all the tools needed to manage caching of data from the APIs and authentication. Linking of data between APIs and retry of requests when authentication has expired is all managed automatically.

The Frollo Android SDK is broken down into multiple components that reflect the features on our APIs. At a high level the features are broken down as follows:

Authentication

Authentication of the user is currently managed by use of OAuth2. Users can be authenticated by any OpenID Connect compliant identity provider or the Frollo identity provider.

Authentication is supported using the following OAuth2 flows:

Authentication provides the access token needed to access Frollo APIs and manages refreshing the access token if it expires.

See OAuth2Authentication for more details.

User

User management provides utilities to manage the user profile and device. The user profile can contain personal information about the user used to personalise the Frollo experience, for example providing location relevant recommendations and comparisons on spending.

The following are taken care of here:

The following are available depending on how authentication and users are configured for your tenant:

See UserManagement for more details.

Aggregation

Aggregation manages the user's financial and other accounts data. This gives an aggregate view of a user's bank accounts, loans, credit information, loyalty, insurance and other data. Linking and customisation of this data is also managed here.

Account data can come from many different sources including:

An institution is referred to as a Provider and the login or connection to that provider as a ProviderAccount. The actual account data is referred to as an Account as each provider account may have multiple accounts linked to it. An example would be:

Supported account types include:

Transactions can support tagging for personalisation at a granular level or allow for spending breakdown to be mesaured at higher level through automatic categorisation and allocation to "buckets". Buckets include income, living, lifestyle and savings. Naming of these buckets can be changed at the UI level and allocation between them can be determined by configuration of the host tenant. These are referred to as a BudgetCategory in the API.

The following features are part of aggregation:

Note: Aggregation refers the the aggregated view of accounts seen within Frollo, wether this includes accounts from external aggregation partners will depend on how your tenant is configured.

See Aggregation for more details.

Bills

Bills allows users to manage bills and track payments against them. Bill detection is automatic and users can then confirm they wish to track payments against these bills or a user can add manual bills if needed.

The following features are part of bills:

See Bills for more details.

Budget and Pay Day

Budgets and pay day allow the user to setup a budget based on their own pay cycle. Budgets can be setup to track spending against merchants, categories and buckets. Setting up budgets at the bucket level allows users to group spending together and easily track against proven budgeting methods (e.g. envelope or buckets).

The following features are part of budgets and pay day:

Coming Soon to SDK

Reports

Reports give a breakdown of a user's spending or an account balance history. Reports can be used to show the user spending in the current month or allow the user to drill down and explore their spend in a variety of ways. Reports data is also suitable for driving graphs.

Reports can be generated across different time periods and broken down into several different ways including by category, by merchant and by bucket.

The following features are part of reports:

See Reports for more details.

Goals

Goals help the user set savings or debt repayment goals and meet them. Goals allow the user to set a target amount and/or date and/or how much they can afford each month and their target date/repayment/total is calculated from this. Savings towards this goal are automatically tracked from deposits to an associated bank or savings account.

The following features are part of goals and challenges:

See Goals for more details.

Events

Events allow user actions to drive changes or chains of actions on the Frollo host. For example a user could reach some fitness goals using HealthKit and trigger an event to increase their lifestyle budget for the next week as a reward.

See Events for more details.

Messages

Messages allow feedback to be provided to the user in the form of nudges and other content. Messages are a customisable content delivery system allowing the system to provide reminders back to the user to keep on track, drive offers or any manner of content the user may need.

The following features are supported as part of messages:

See Messages for more details

Surveys

Surveys allow you to collect feedback and conduct surveys from the user. This can be used to find how a user feels about their financial situation and drive events based on that or even just get feedback on the consuming application.

The following features are supported as part of surveys:

See Surveys for more details

Changelog

3.4.0

Features

Changes

3.3.0

Features

Changes

3.2.0

Changes

3.1.0

Changes

3.0.0

Changes

2.1.0

Changes

Features

2.0.5

Changes

2.0.4

Changes

2.0.3

Changes

2.0.2

Changes

2.0.1

Changes

2.0.0

Features

1.4.4

Changes

1.4.3

Changes

1.4.2

Changes

1.4.1

Changes

1.4.0

Changes

1.3.4

Changes

1.3.3

Changes

1.3.2

Changes

1.3.1

Changes

1.3.0

Features

1.2.0

Features

1.1.0

Features

1.0.0

Features

Getting Started

Requirements

Integration instructions

To integrate Frollo Android SDK to your Android app use the following steps:

Integration using AAR file

  1. Goto File > New > New Module > Import JAR/AAR Package
  2. Select the file frollo-android-sdk-release-3.3.0.aar and Finish
  3. Add below line to the dependencies in your app/build.gradle file

     dependencies {
            //..
            implementation project(":frollo-android-sdk-release-3.3.0")
        }
    
  4. Copy the provided frollosdk.gradle file to your project's root directory
  5. Add this line just below your apply plugins in your app/build.gradle file

     apply from: '../frollosdk.gradle'
    
  6. Define a appAuthRedirectScheme in your module level build.gradle. This should be unique redirect uri for your app.

    Example: If your redirect url is frollo-sdk-example://authorize, then you would do as below

    defaultConfig {
           //..
           manifestPlaceholders = ['appAuthRedirectScheme': 'frollo-sdk-example']
           //..
       }
    

    For more details see Integration Requirements under OAuth2 Authentication using Authorization Code

  7. Frollo SDK disables auto-backup by default to ensure no data persists between installs. You might run into conflicts during integration if your app has defined android:allowBackup="true" in its manifest. Either you can disable auto-backup for your app or override by adding tools:replace="android:allowBackup" to <application> element in your AndroidManifest.xml.
  8. If you have enabled progaurd please add below lines to your progaurd rules file

    # KEEP FROM OBFUCATION - Frollo SDK
       -keep class us.frollo.frollosdk.** {*;}
       -keepclassmembers  class us.frollo.frollosdk.** {*;}
    
  9. Build!

Integration by cloning SDK code base

  1. Pull the Frollo SDK code base

    or

    You should see a folder named frollo-android-sdk inside your root project directory and within it, the SDK code.

    Checkout a stable release branch

    cd frollo-android-sdk

    git fetch

    git checkout release/3.3.0 (replace the version number with the most stable version number)

  2. Add frollo-android-sdk module to your settings.gradle file

    include ':app', ':frollo-android-sdk'

  3. Add below line to the dependencies in your app/build.gradle file

     dependencies {
            //..
            implementation project(":frollo-android-sdk")
        }
    
  4. Define a appAuthRedirectScheme in your module level build.gradle. This should be unique redirect uri for your app.

    Example: If your redirect url is frollo-sdk-example://authorize, then you would do as below

    defaultConfig {
           //..
           manifestPlaceholders = ['appAuthRedirectScheme': 'frollo-sdk-example']
           //..
       }
    

    For more details see Integration Requirements under OAuth2 Authentication using Authorization Code

  5. Frollo SDK disables auto-backup by default to ensure no data persists between installs. You might run into conflicts during integration if your app has defined android:allowBackup="true" in its manifest. Either you can disable auto-backup for your app or override by adding tools:replace="android:allowBackup" to <application> element in your AndroidManifest.xml.
  6. If you have enabled progaurd please add below lines to your progaurd rules file

    # KEEP FROM OBFUCATION - Frollo SDK
       -keep class us.frollo.frollosdk.** {*;}
       -keepclassmembers  class us.frollo.frollosdk.** {*;}
    
  7. Build! 👷‍♂️

Integration using AAR file inside 'libs' folder of another library module

  1. Place the Frollo SDK AAR file inside the 'libs' folder in the desried library module
  2. Add below line to the dependencies in your <library module name>/build.gradle file

     dependencies {
            //..
            implementation(name: 'frollo-android-sdk-release-3.3.0', ext: 'aar')
        }
    
  3. Add below to your project level build.gradle file

     allprojects {
            //..
            repositories {
                //..
                flatDir {
                    dirs project(':<library module name>').file('libs')
                }
            }
        }
    
  4. Copy the provided frollosdk.gradle file to your library module's directory
  5. Add this line just below your apply plugins in your <library module name>/build.gradle file

     apply from: 'frollosdk.gradle'
    
  6. Define a appAuthRedirectScheme in your app and module level build.gradle files. This should be unique redirect uri for your app.

    Example: If your redirect url is frollo-sdk-example://authorize, then you would do as below

    defaultConfig {
           //..
           manifestPlaceholders = ['appAuthRedirectScheme': 'frollo-sdk-example']
           //..
       }
    

    For more details see Integration Requirements under OAuth2 Authentication using Authorization Code

  7. Frollo SDK disables auto-backup by default to ensure no data persists between installs. You might run into conflicts during integration if your app has defined android:allowBackup="true" in its manifest. Either you can disable auto-backup for your app or override by adding tools:replace="android:allowBackup" to <application> element in your AndroidManifest.xml.
  8. If you have enabled progaurd please add below lines to your progaurd rules file

    # KEEP FROM OBFUCATION - Frollo SDK
       -keep class us.frollo.frollosdk.** {*;}
       -keepclassmembers  class us.frollo.frollosdk.** {*;}
    
  9. Build!

Basic Usage

SDK Setup

Import the FrolloSDK and ensure you run setup with your tenant URL provided by us. Do not attempt to use any APIs before the setup completion handler returns. You will also need to pass in your custom authentication handler or use the default OAuth2 implementation.

    class MyApplication : Application() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)

            // OAuth2 Config
            val configuration = FrolloSDKConfiguration(
                                      authenticationType = OAuth2(
                                              redirectUrl = "<REDIRECT_URI>",
                                              authorizationUrl = "https://id.frollo.us/oauth/authorize",
                                              tokenUrl = "https://id.frollo.us/oauth/token"),
                                      clientId = "<APPLICATION_CLIENT_ID>",
                                      serverUrl = "https://<API_TENANT>.frollo.us/api/v2/")

            // Custom Authentication Config
            val customAuthentication = CustomAuthentication()
            val configuration = FrolloSDKConfiguration(
                                      authenticationType = Custom(
                                              accessTokenProvider = customAuthentication,
                                              authenticationCallback = customAuthentication),
                                      clientId = "<APPLICATION_CLIENT_ID>",
                                      serverUrl = "https://<API_TENANT>.frollo.us/api/v2/")

            FrolloSDK.setup(this, configuration = configuration) { result ->
                when (result.status) {
                    Result.Status.SUCCESS -> completeSetup()
                    Result.Status.ERROR -> Log.e(TAG, result.error?.localizedDescription)
                }
            }
        }
    }

Authentication

Before any data can be refreshed for a user they must be authenticated first. If using OAuth2 authentication you can check the logged in status of the user on the OAuth2Authentication class.

    if (FrolloSDK.oAuth2Authentication.loggedIn) {
        showMainActivity()
    } else {
        showLoginActivity()
    }

If the user is not authenticated then the user must login or an access token must be provided by the custom Authentication access token provider. Authentication can be done using OAuth2 or a custom implementation can be provided if you wish to manage the user's access token manually or share it with other APIs.

OAuth2 Authentication

Using OAuth2 based authentication Resource Owner Password Credential flow and Authorization Code with PKCE flow are supported. Identity Providers must be OpenID Connect compliant to use the in-built OAuth2Authentication authentication class. If using OAuth2 authentication you can use oAuth2Authentication

ROPC Flow

Using the ROPC flow is the simplest and can be used if you are implementing the SDK in your own highly trusted first party application. All it requires is email and password and can be used in conjunction with a native UI.

See loginUser(email:password:completion:)

    FrolloSDK.oAuth2Authentication.loginUser(email = "jacob@example.com", password = "$uPer5ecr@t") { result ->
        when (result.status) {
            Result.Status.ERROR -> displayError(result.error?.localizedDescription, "Login Failed")
            Result.Status.SUCCESS -> completeLogin()
        }
    }

Authorization Code with PKCE Flow

Authenticating the user using Authorization Code flow involves a couple of extra steps to configure. The first is to present the ChromeTabs to the user to take them through the web based authorization flow. The Activity this should be presented from must be passed to the SDK.

See loginUserUsingWeb

Integration Requirements
Method 1 - Using Pending Intents

Completion intent and Cancelled intent should be provided to the SDK to support web based OAuth2 login and other links that can affect application behaviour.

    class LoginActivity : AppCompatActivity() {

        override fun onCreate(savedInstanceState: Bundle?) {
            //...
            startAuthorizationCodeFlow()
        }

        private fun startAuthorizationCodeFlow() {
            val completionIntent = Intent(this, CompletionLoginWebActivity::class.java)

            val cancelIntent = Intent(this, LoginActivity::class.java)
            cancelIntent.putExtra(EXTRA_FAILED, true)
            cancelIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP

            FrolloSDK.oAuth2Authentication.loginUserUsingWeb(
                    activity = this,
                    scopes = listOf(OAuth2Scope.OFFLINE_ACCESS, OAuth2Scope.EMAIL, OAuth2Scope.OPENID),
                    completedIntent = PendingIntent.getActivity(this, 0, completionIntent, 0),
                    cancelledIntent = PendingIntent.getActivity(this, 0, cancelIntent, 0),
                    toolBarColor = resources.getColor(R.color.colorPrimary, null))
        }
    }

The next step is to pass the intent received by the Completion Activity to the SDK to complete the login process and exchange the authorization code for a token.

    class CompletionLoginWebActivity : AppCompatActivity() {

        override fun onCreate(savedInstanceState: Bundle?) {
            //...
            FrolloSDK.oAuth2Authentication.handleWebLoginResponse(intent) { result ->
                when (result.status) {
                    Result.Status.SUCCESS -> {
                        startActivity<MainActivity>()
                        finish()
                    }

                    Result.Status.ERROR -> displayError(result.error?.localizedDescription, "Login Failed")
                }
            }
        }
    }
Method 2 - Using onActivityResult Callback
    class LoginActivity : AppCompatActivity() {

        override fun onCreate(savedInstanceState: Bundle?) {
            //...
            startAuthorizationCodeFlow()
        }

        private fun startAuthorizationCodeFlow() {
            FrolloSDK.authentication.loginUserUsingWeb(
                    activity = this,
                    scopes = listOf(OAuth2Scope.OFFLINE_ACCESS, OAuth2Scope.EMAIL, OAuth2Scope.OPENID),
                    toolBarColor = resources.getColor(R.color.colorPrimary, null))
        }

        override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
            super.onActivityResult(requestCode, resultCode, data)

            if (requestCode == Authentication.RC_AUTH) {
                if (resultCode == RESULT_CANCELED) {
                    displayAuthCancelled();
                } else {
                    // The next step is to pass the intent received to the SDK to complete the login process and exchange the authorization code for a token.
                    FrolloSDK.authentication.handleWebLoginResponse(intent) { result ->
                        when (result.status) {
                            Result.Status.SUCCESS -> {
                                startActivity<MainActivity>()
                                finish()
                            }

                            Result.Status.ERROR -> displayError(result.error?.localizedDescription, "Login Failed")
                        }
                    }
                }
            }
        }
    }

Custom Authentication

Custom authentication can be provided by conforming to the AccessTokenProvider interface and AuthenticationCallback interface ensuring all interface functions are implemented appropriately.

Refreshing Data

After logging in, your cache will be empty in the SDK. Refresh important data such as Messages immediately after login.

    FrolloSDK.messages.refreshUnreadMessages { result ->
        when (result.status) {
            Result.Status.ERROR -> displayError(result.error?.localizedDescription, "Refreshing Messages Failed")
            Result.Status.SUCCESS -> Log.d("Accounts Refreshed")
        }
    }

Alternatively refresh data on startup in an optimized way using refreshData on the main SDK. This will refresh important user data first, delaying less important ones until later.

    FrolloSDK.refreshData()

Retrieving Cached Data

Fetching objects from the cache store is easy. Just call the SDK fetch APIs and observe the returned LiveData.

    FrolloSDK.messages.fetchMessages(read = false).observe(owner, Observer<Resource<List<Message>>> { resource ->
        when (resource?.status) {
            Resource.Status.SUCCESS -> loadMessages(resource.data)
            Resource.Status.ERROR -> displayError(result.error?.localizedDescription, "Fetching Messages Failed")
        }
    })

Lifecyle Handlers (Optional)

Optionally implement the lifecycle handlers by extending Application class to ensure FrolloSDK can keep cached data fresh when suspending and resuming the app.

    class MyApplication : Application(), LifecycleObserver {

        override fun onCreate() {
            super.onCreate()
            ProcessLifecycleOwner.get().lifecycle.addObserver(this)
        }

        @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
        fun onAppBackgrounded() {
            FrolloSDK.onAppBackgrounded()
        }

        @OnLifecycleEvent(Lifecycle.Event.ON_START)
        fun onAppForegrounded() {
            FrolloSDK.onAppForegrounded()
        }
    }

Push Notifications

Setup

Follow the steps here and here to setup Firebase client for Android.

Registering for Notifications

            FirebaseInstanceId.getInstance().instanceId
                .addOnCompleteListener(OnCompleteListener { task ->
                    if (!task.isSuccessful) {
                        Log.w(TAG, "getInstanceId failed", task.exception)
                        return@OnCompleteListener
                    }

                    // Get new Instance ID token
                    val token = task.result?.token
                    token?.let { FrolloSDK.notifications.registerPushNotificationToken(it) }
                })
            class MyFirebaseMessagingService : FirebaseMessagingService() {
                override fun onNewToken(token: String?) {
                    token?.let { FrolloSDK.notifications.registerPushNotificationToken(it) }
                }
            }

Handling Notifications and Events

            class MyFirebaseMessagingService : FirebaseMessagingService() {
                override fun onMessageReceived(remoteMessage: RemoteMessage?) {
                    remoteMessage?.data?.let { data ->
                        if (data.isNotEmpty()) {
                            FrolloSDK.notifications.handlePushNotification(data)
                        }
                    }
                }
            }
            intent.extras?.let {
                FrolloSDK.notifications.handlePushNotification(it)
            }

Reference

Packages

us.frollo.frollosdk

FrolloSDK manages the lifecycle of the SDK. Only one instance should be instantiated and then used (after setup completes) during the lifetime of the app.

us.frollo.frollosdk.aggregation

Manages all aggregation data including accounts, transactions, categories and merchants.

us.frollo.frollosdk.authentication

Authentication manages the authentication of the user, managing the user profile and logout of the user.

us.frollo.frollosdk.base

Frollo SDK base classes

us.frollo.frollosdk.bills

Manages bills and bill payments

us.frollo.frollosdk.budgets

us.frollo.frollosdk.core

Frollo SDK core classes

us.frollo.frollosdk.error

Types of Frollo SDK errors

us.frollo.frollosdk.events

Handles events and allows triggering of events on the host.

us.frollo.frollosdk.goals

Tracking and managing goals

us.frollo.frollosdk.logging

Frollo SDK logging

us.frollo.frollosdk.messages

Manages refreshing and caching of messages.

us.frollo.frollosdk.model

Frollo SDK data models

us.frollo.frollosdk.model.api.shared

Frollo SDK shared models

us.frollo.frollosdk.model.coredata.aggregation.accounts

Frollo SDK account models

us.frollo.frollosdk.model.coredata.aggregation.merchants

Frollo SDK merchant models

us.frollo.frollosdk.model.coredata.aggregation.provideraccounts

Frollo SDK provider account models

us.frollo.frollosdk.model.coredata.aggregation.providers

Frollo SDK provider models

us.frollo.frollosdk.model.coredata.aggregation.tags

Frollo SDK transaction user tag models

us.frollo.frollosdk.model.coredata.aggregation.transactioncategories

Frollo SDK transaction category models

us.frollo.frollosdk.model.coredata.aggregation.transactions

Frollo SDK transaction models

us.frollo.frollosdk.model.coredata.bills

Frollo SDK bill and bill payment models

us.frollo.frollosdk.model.coredata.budgets

us.frollo.frollosdk.model.coredata.goals

Frollo SDK goal models

us.frollo.frollosdk.model.coredata.messages

Frollo SDK message models

us.frollo.frollosdk.model.coredata.reports

Frollo SDK report models

us.frollo.frollosdk.model.coredata.shared

Frollo SDK shared models

us.frollo.frollosdk.model.coredata.surveys

Frollo SDK survey models

us.frollo.frollosdk.model.coredata.user

Frollo SDK user models

us.frollo.frollosdk.model.display.aggregation.providers

Frollo SDK provider display models

us.frollo.frollosdk.model.oauth

Frollo SDK OAuth2 models

us.frollo.frollosdk.notifications

Manages registration for and handling of incoming push notifications.

us.frollo.frollosdk.reports

Manages all aspects of reporting of aggregation data including spending and balances.

us.frollo.frollosdk.surveys

Manages fetching & submitting surveys.

us.frollo.frollosdk.user

Manages the user details and device

Index

All Types