Flipper

Another possibility is to integrate Flipper. Flipper is a library from Facebook that you can integrate into debug builds of your app. It opens a port that a Flipper-supplied desktop app can connect to. Depending on what Flipper plugins you have enabled, that desktop app can do different things… with one being giving you Database Inspector-style access to your app’s database.

The PagedFTS module of the book’s primary sample project — profiled elsewhere in the book — happens to integrate Flipper.

Adding Dependencies

Flipper takes an approach used by a few debugging-centric libraries: have some real dependencies to add to debug builds and a “no-op” dependency to add to release builds. The objective is to allow for configuration to be the same regardless of build type, while avoiding the risk of shipping debug-related code to your users.

PagedFTS, therefore, has two debugImplementation lines and one releaseImplementation line in its dependencies list:

  debugImplementation 'com.facebook.flipper:flipper:0.96.1'
  debugImplementation 'com.facebook.soloader:soloader:0.10.1'

  releaseImplementation 'com.facebook.flipper:flipper-noop:0.96.1'

Configuring Flipper for Database Debugging

Flipper is designed to be configured from onCreate() of a custom Application class. PagedFTS has such a class, named KoinApp:

package com.commonsware.room.fts

import android.app.Application
import com.facebook.flipper.android.AndroidFlipperClient
import com.facebook.flipper.android.utils.FlipperUtils
import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin
import com.facebook.flipper.plugins.inspector.DescriptorMapping
import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin
import com.facebook.soloader.SoLoader
import org.koin.android.ext.koin.androidContext
import org.koin.android.ext.koin.androidLogger
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.core.context.startKoin
import org.koin.dsl.module


class KoinApp : Application() {
  private val koinModule = module {
    single { BookDatabase.newInstance(androidContext()) }
    single { BookRepository(get()) }
    viewModel { BookViewModel(get()) }
    viewModel { (search: String) -> SearchViewModel(search, get()) }
  }

  override fun onCreate() {
    super.onCreate()

    startKoin {
      androidLogger()
      androidContext(this@KoinApp)
      modules(koinModule)
    }

    if (BuildConfig.DEBUG && FlipperUtils.shouldEnableFlipper(this)) {
      SoLoader.init(this, false)

      AndroidFlipperClient.getInstance(this).also { client ->
        client.addPlugin(DatabasesFlipperPlugin(this))

        client.start()
      }
    }
  }
}

Part of onCreate() is setting up Koin for dependency inversion. However, the last few lines of onCreate() are focused on Flipper initialization:

    if (BuildConfig.DEBUG && FlipperUtils.shouldEnableFlipper(this)) {
      SoLoader.init(this, false)

      AndroidFlipperClient.getInstance(this).also { client ->
        client.addPlugin(DatabasesFlipperPlugin(this))

        client.start()
      }
    }

The key, for being able to debug databases using Flipper, is adding the DatabasesFlipperPlugin to Flipper. Flipper operates based on a series of plugins, and this one provides access to SQLite databases, at least those in standard locations. The documentation for that plugin provides some other options, particularly for databases residing in non-standard locations.

See the Flipper documentation for more details about this initialization/configuration process.

Obtaining and Using the Desktop App

The Flipper site has download options for Linux, macOS, and Windows versions of the desktop app. Windows and Linux are bare ZIP files containing the React Native app; macOS gets a proper DMG file.

If you run your Flipper-enabled app, then run the Flipper desktop app, your app will appear in a section in the accordion on the left of the desktop app, and you can enable the Databases tool via a switch:

Flipper, Showing PagedFTS App and Databases Tool
Flipper, Showing PagedFTS App and Databases Tool

You can choose the database and table via drop-downs towards the top of the Databases content pane. The default view is “Data”, showing you the contents of your selected table:

Flipper, Showing Contents of paragraphs Table
Flipper, Showing Contents of paragraphs Table

You can view your table schema either in the form of SQL via the “Table Info” tab or as a table in the “Structure” tab. And the “SQL” tab lets you execute arbitrary SQL statements, showing you query results below the text area:

Flipper, Showing Results of SQL Query
Flipper, Showing Results of SQL Query

Prev Table of Contents Next

This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.