Introducing the FeedbackKit Kotlin SDK
On 9 February we released Kotlin SDK 1.0, the Android library that brings FeedbackKit into your app. It gives an Android app a board where people read what others have asked for, vote, and file their own requests, built from Jetpack Compose screens that come with the library. Your team then reads, sorts and answers those requests in FeedbackKit.
The short version
- Install
com.getfeedbackkit:feedbackkit:1.0.1from Maven Central. 1.0.1 replaces 1.0.0, whose default address had no FeedbackKit server behind it. - Three screens as composables:
FeedbackList,FeedbackDetailViewandSubmitFeedbackView, built fromFeedbackCard,VoteButton,StatusBadgeandCategoryBadge. - A coroutine client,
FeedbackKit.shared, withfeedback,votesandcommentsAPIs for your own screens. - Light and dark themes, with a colour for each of the six statuses and four categories.
- It needs minSdk 24 and Java 17.
- 1.0 has known issues with voting, comments and the email field. They are listed below, so read that section before you ship.
What is in Kotlin SDK 1.0
Three screens
FeedbackList is the board. It loads the project's requests, most-voted at the top, and shows each one as a card with a vote button, its status and category badges, its title, two lines of its description and a comment count. It has its own loading, empty and error states, and each one can be swapped for your own composable. The list's state lives in rememberFeedbackListState(), which can start filtered to a status or a category and exposes refresh(), filterByStatus(), filterByCategory() and clearFilters().
SubmitFeedbackView is the form: a title, a category (Feature Request, Bug Report, Improvement or Other), a description and an optional email. The submit button stays disabled until the title and the description are filled in, and onSubmitSuccess hands you the new request.
FeedbackDetailView shows one request: the vote button, the badges, the title, the full description and the comments. Both the form and the detail screen bring a top app bar with a back arrow, and showAppBar = false drops it when your own scaffold already has one.
The screens do not navigate by themselves. You decide where each one lives, through callbacks such as onFeedbackClick and onBack, which suits Navigation Compose or any other setup.
Statuses and voting
Each request shows one of six statuses: Pending, Approved, In Progress, TestFlight, Completed or Rejected. Android users see the TestFlight name too, since it is the status's name rather than a platform. FeedbackStatus.canVote is false for Completed and Rejected, and the vote button is disabled on those requests. The button updates its count as soon as it is tapped, then settles on what the server returns.
A client for your own screens
Everything the screens do goes through FeedbackKit.shared: feedback.list(), feedback.get(id) and feedback.create(title, description, category, email), votes.vote(), votes.unvote() and votes.toggleVote(), and comments.list() and comments.create(). They are suspend functions, and they throw a FeedbackKitError, a sealed class with a case per failure: an invalid API key, a plan limit, a missing item, a conflict such as a repeat vote, a network error, a server error. Each case carries a userMessage you can show as it is.
Theming
FeedbackKitTheme is a data class with Light and Dark presets. It holds the primary, background, card, text, border and vote colours, a StatusColors and a CategoryColors, plus corner radius and spacing. Pass it to FeedbackKitProvider and every screen inside picks it up, or pass a theme to one composable.
Known issues in 1.0
Some of the library's requests and responses do not match what the FeedbackKit server sends and expects. Here is what that means in an app:
- Voting. A vote is saved, but the library cannot read the server's reply, so the button rolls back to its previous count. The vote shows once the list reloads. Removing a vote fails, so a vote cast from 1.0 stays.
- Comments. A request with no comments shows an empty comment section. Once a request has a comment, the section shows "Failed to load comments" instead. The detail screen has no field for writing a comment.
- Email. The address typed into the form's email field does not reach FeedbackKit, so that person is not emailed when the status changes.
- A user id is required. The library does not create one, and the server refuses a new request or a vote without it. Set
userIdwhen you configure.
Reading the board, filtering it, opening a request and filing one work as described.
Getting started
Add the dependency to your app module's build.gradle.kts, with mavenCentral() among your repositories:
dependencies {
implementation("com.getfeedbackkit:feedbackkit:1.0.1")
}
The library declares the internet permission in its own manifest. Configure it once in your Application class with your project's API key, which you find in FeedbackKit under the project's settings, and an id for the user:
import android.app.Application
import com.swiftlydeveloped.feedbackkit.FeedbackKit
import com.swiftlydeveloped.feedbackkit.configure
class TrailmateApp : Application() {
override fun onCreate() {
super.onCreate()
FeedbackKit.configure(this) {
apiKey = "sf_your_api_key"
userId = "trailmate-user-4821"
}
}
}
Then show the board inside a provider:
@Composable
fun IdeasScreen(onOpen: (Feedback) -> Unit) {
FeedbackKitProvider(theme = FeedbackKitTheme.Light) {
FeedbackList(onFeedbackClick = onOpen)
}
}
The Kotlin packages are named com.swiftlydeveloped.feedbackkit, while the Maven group is com.getfeedbackkit. The Kotlin SDK 1.0 tutorial walks through the rest: the user id, navigation between the three screens, filters, theming and testing. The reference is in the Kotlin SDK docs.
How FeedbackKit fits in
The SDK is the part your users see. Your team works in the FeedbackKit admin app for iPhone, iPad and Mac, or in the web admin: read new requests, merge duplicates, reply in the comments, sort by votes, and move a request through Approved, In Progress and TestFlight to Completed. The team gets a push notification for new requests and comments. On Pro and up, requests can go to GitHub, Linear, Notion, ClickUp or Monday.com. See pricing for what each plan includes.
Here is how a new request arrives in FeedbackKit, with sample data from a fictional hiking app:
Requests from inside the app
What comes next
Server-side Swift is next, with the Vapor SDK. If you are starting an Android integration today, the current Android tutorial covers the latest version.
Every plan includes the Kotlin SDK. Start free, create a project, and put the board in your next build.