-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Add Android new User Feedback instructions #13758
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
stefanosiano
wants to merge
3
commits into
master
Choose a base branch
from
stefanosiano/android-user-widget
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
235 changes: 235 additions & 0 deletions
235
docs/platforms/android/user-feedback/configuration/index.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,235 @@ | ||
--- | ||
title: Configure User Feedback | ||
sidebar_order: 6900 | ||
description: "Learn about general User Feedback configuration fields." | ||
--- | ||
|
||
## User Feedback Widget | ||
|
||
The User Feedback Widget offers many customization options, and if the available options are insufficient, you can [use your own UI](#bring-your-own-widget). | ||
|
||
### General | ||
|
||
Some hooks are available so you can react to the user opening and closing the form, when the user successfully submits the form or when there is an error: | ||
|
||
| Hook | Type | Description | | ||
| ----------------- | ------------------------- | ------------------------------------------------------------------------ | | ||
| `onFormOpen` | `() -> Void` | Called when the feedback form is opened. | | ||
| `onFormClose` | `() -> Void` | Called when the feedback form is closed. | | ||
| `onSubmitSuccess` | `(Feedback) -> Void` | Called when feedback is successfully submitted via the prepared form. | | ||
| `onSubmitError` | `(Feedback) -> Void` | Called when there is an error submitting feedback via the prepared form. | | ||
|
||
`onSubmitSuccess` and `onSubmitError` forward the feedback object that was submitted, which contains the following properties: | ||
|
||
- `message`: The message the user entered in the feedback form. | ||
- `name`: The name the user entered in the feedback form. | ||
- `contactEmail`: The email the user entered in the feedback form. | ||
|
||
Example: | ||
|
||
```java | ||
SentryAndroid.init(context, options -> { | ||
options.getFeedbackOptions().setOnFormOpen(() -> System.out.println("Form opened")); | ||
options.getFeedbackOptions().setOnFormClose(() -> System.out.println("Form closed")); | ||
options.getFeedbackOptions().setOnSubmitSuccess((feedback) -> System.out.println("Feedback submitted successfully: " + feedback.toString())); | ||
options.getFeedbackOptions().setOnSubmitError((feedback) -> System.out.println("Failed to submit feedback: " + feedback.toString())); | ||
}); | ||
``` | ||
```kotlin | ||
SentryAndroid.init(this) { options -> | ||
options.feedbackOptions.onFormOpen = Runnable { println("Form opened") } | ||
options.feedbackOptions.onFormClose = Runnable { println("Form closed") } | ||
options.feedbackOptions.onSubmitSuccess = SentryFeedbackOptions.SentryFeedbackCallback { | ||
println("Feedback submitted successfully: $it") | ||
} | ||
options.feedbackOptions.onSubmitError = SentryFeedbackOptions.SentryFeedbackCallback { | ||
println("Failed to submit feedback: $it") | ||
} | ||
} | ||
``` | ||
|
||
### Form Configuration | ||
|
||
You can customize which form elements are shown, whether they are required, and even prefill some info, in `SentryOptions.SentryFeedbackOptions`: | ||
|
||
| Option | Type | Default | Description | | ||
| ----------------------------- | -------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | | ||
| `showBranding` | `Bool` | `true` | Displays the Sentry logo inside the form | | ||
| `isNameRequired` | `Bool` | `false` | Requires the name field on the feedback form to be filled in. | | ||
| `showName` | `Bool` | `true` | Displays the name field on the feedback form. Ignored if `isNameRequired` is `true`. | | ||
| `isEmailRequired` | `Bool` | `false` | Requires the email field on the feedback form to be filled in. | | ||
| `showEmail` | `Bool` | `true` | Displays the email field on the feedback form. Ignored if `isEmailRequired` is `true`. | | ||
| `useSentryUser` | `Bool` | `true` | Sets the `email` and `name` fields to the corresponding Sentry SDK user fields that were called with `SentrySDK.setUser`. | | ||
|
||
Example: | ||
|
||
```xml {filename:AndroidManifest.xml} | ||
<application> | ||
<meta-data android:name="io.sentry.feedback.is-name-required" android:value="true" /> | ||
<meta-data android:name="io.sentry.feedback.show-name" android:value="false" /> | ||
<meta-data android:name="io.sentry.feedback.is-email-required" android:value="false" /> | ||
<meta-data android:name="io.sentry.feedback.show-email" android:value="false" /> | ||
<meta-data android:name="io.sentry.feedback.use-sentry-user" android:value="false" /> | ||
<meta-data android:name="io.sentry.feedback.show-branding" android:value="false" /> | ||
</application> | ||
``` | ||
```java | ||
SentryAndroid.init(context, options -> { | ||
options.getFeedbackOptions().setNameRequired(true); | ||
options.getFeedbackOptions().setShowName(false); | ||
options.getFeedbackOptions().setEmailRequired(true); | ||
options.getFeedbackOptions().setShowEmail(false); | ||
options.getFeedbackOptions().setUseSentryUser(false); | ||
options.getFeedbackOptions().setShowBranding(false); | ||
}); | ||
``` | ||
```kotlin | ||
SentryAndroid.init(this) { options -> | ||
options.feedbackOptions.isNameRequired = true | ||
options.feedbackOptions.isShowName = false | ||
options.feedbackOptions.isEmailRequired = true | ||
options.feedbackOptions.isShowEmail = false | ||
options.feedbackOptions.isUseSentryUser = false | ||
options.feedbackOptions.isShowBranding = false | ||
} | ||
``` | ||
|
||
### Form Labels Configuration | ||
|
||
You can customize tha labels and placeholders used in the form. | ||
Note: manifest options are not supported here, due to internationalization: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe the note should be an |
||
|
||
| Option | Type | Default | Description | | ||
| ----------------------------- | -------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | | ||
| `formTitle` | `String` | `"Report a Bug"` | The title of the feedback form. | | ||
| `messageLabel` | `String` | `"Description"` | The label of the feedback description input field. | | ||
| `messagePlaceholder` | `String` | `"What's the bug? What did you expect?"` | The placeholder in the feedback description input field. | | ||
| `isRequiredLabel` | `String` | `" (Required)"` | The text to attach to the title label for a required field. | | ||
| `successMessageText` | `String` | `"Thank you for your report!"` | The message displayed after a successful feedback submission. | | ||
| `nameLabel` | `String` | `"Name"` | The label next to the name input field. | | ||
| `namePlaceholder` | `String` | `"Your Name"` | The placeholder in the name input field. | | ||
| `emailLabel` | `String` | `"Email"` | The label next to the email input field. | | ||
| `emailPlaceholder` | `String` | `"[email protected]"` | The placeholder in the email input field. | | ||
| `submitButtonLabel` | `String` | `"Send Bug Report"` | The label of the submit button. | | ||
| `cancelButtonLabel` | `String` | `"Cancel"` | The label of the cancel button. | | ||
|
||
Example: | ||
|
||
```java | ||
SentryAndroid.init(context, options -> { | ||
options.getFeedbackOptions().setFormTitle("We want to hear from you!"); | ||
options.getFeedbackOptions().setMessageLabel("Feedback"); | ||
options.getFeedbackOptions().setMessagePlaceholder("Type your feedback"); | ||
options.getFeedbackOptions().setIsRequiredLabel(" *"); | ||
options.getFeedbackOptions().setSuccessMessageText("Thanks for the feedback!"); | ||
options.getFeedbackOptions().setNameLabel("Full Name"); | ||
options.getFeedbackOptions().setNamePlaceholder("Type your full name"); | ||
options.getFeedbackOptions().setEmailLabel("Email Address"); | ||
options.getFeedbackOptions().setEmailPlaceholder("Type your email"); | ||
options.getFeedbackOptions().setSubmitButtonLabel("Submit"); | ||
options.getFeedbackOptions().setCancelButtonLabel("Back"); | ||
}); | ||
``` | ||
```kotlin | ||
SentryAndroid.init(this) { options -> | ||
options.feedbackOptions.formTitle = "We want to hear from you!" | ||
options.feedbackOptions.messageLabel = "Feedback" | ||
options.feedbackOptions.messagePlaceholder = "Type your feedback" | ||
options.feedbackOptions.isRequiredLabel = " *" | ||
options.feedbackOptions.successMessageText = "Thanks for the feedback!" | ||
options.feedbackOptions.nameLabel = "Full Name" | ||
options.feedbackOptions.namePlaceholder = "Type your full name" | ||
options.feedbackOptions.emailLabel = "Email Address" | ||
options.feedbackOptions.emailPlaceholder = "Type your email" | ||
options.feedbackOptions.submitButtonLabel = "Submit" | ||
options.feedbackOptions.cancelButtonLabel = "Back" | ||
} | ||
``` | ||
|
||
### Theme Customization | ||
|
||
The User Feedback form integrates with the app theme by default, and can be customized with a custom xml style. | ||
Here are the attributes used by the form: | ||
|
||
| Android style attribute | Description | | ||
| --------------------------------- | ----------------------------------------------------------- | | ||
| `android:windowTitleStyle` | Style of the feedback dialog title | | ||
| `android:textColor` | Color of title, cancel button text, and non-editable texts. | | ||
| `android:editTextColor` | Color of editable texts. | | ||
| `android:textColorHint` | Color of the hint of editable texts. | | ||
| `android:textColorPrimaryInverse` | Color of the send button text. | | ||
| `android:colorPrimary` | Background color of the send button. | | ||
| `android:colorBackground` | Background color of the cancel button. | | ||
| `android:colorForeground` | Color tint of the image logo. | | ||
|
||
The theme used by the form is the one set in the application theme as the `android:dialogTheme`. | ||
Since the SentryUserFeedbackDialog extends AlertDialog, a custom theme can be also set when instantiating it: | ||
|
||
```java | ||
SentryUserFeedbackDialog dialog = new SentryUserFeedbackDialog(context, R.style.MyAppDialogTheme); | ||
``` | ||
```kotlin | ||
val dialog = SentryUserFeedbackDialog(context, R.style.MyAppDialogTheme) | ||
``` | ||
|
||
Here is an example of how the feedback form can be customized: | ||
|
||
```xml {filename:styles.xml} | ||
<!-- Application theme. --> | ||
<style name="MyAppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar"> | ||
<!-- ... Current theme customizations ... --> | ||
|
||
<!-- Set a dialog theme if not already done. --> | ||
<item name="android:dialogTheme">@style/MyAppDialogTheme</item> | ||
</style> | ||
|
||
<!-- Edit application dialog theme. --> | ||
<style name="MyAppDialogTheme" parent="Theme.MaterialComponents.DayNight.Dialog"> | ||
<!-- Set the style of the feedback dialog title. --> | ||
<item name="android:windowTitleStyle">@style/FeedbackFormTitleStyle</item> | ||
|
||
<!-- Set the color of title, cancel button text, and non editable texts. --> | ||
<item name="android:textColor">@color/colorPrimary</item> | ||
<!-- Set the color of editable texts. --> | ||
<item name="android:editTextColor">@color/colorPrimaryDark</item> | ||
<!-- Set the color of the hint of editable texts. --> | ||
<item name="android:textColorHint">@color/colorPrimaryDark</item> | ||
<!-- Set the color of the send button text. --> | ||
<item name="android:textColorPrimaryInverse">@android:color/white</item> | ||
|
||
<!-- Set the background color of the send button. --> | ||
<item name="android:colorPrimary">@color/colorPrimary</item> | ||
<!-- Set the background color of the cancel button. --> | ||
<item name="android:colorBackground">@android:color/black</item> | ||
<!-- Set the color tint of the image logo. --> | ||
<item name="android:colorForeground">@color/colorPrimary</item> | ||
</style> | ||
|
||
<style name="FeedbackFormTitleStyle"> | ||
<!-- Customize your theme here. --> | ||
<item name="android:textAppearance">@style/TextAppearance.AppCompat.Title</item> | ||
</style> | ||
``` | ||
|
||
### Bring Your Own Widget | ||
|
||
You can also use your own UI components to gather feedback and pass the feedback data object to the `Sentry.captureFeedback(Feedback)` function. | ||
|
||
```java | ||
import io.sentry.Sentry; | ||
import io.sentry.protocol.Feedback; | ||
|
||
Feedback feedback = new Feedback("I encountered a bug while using the app."); | ||
feedback.setName("John Doe"); | ||
feedback.setContactEmail("[email protected]"); | ||
Sentry.captureFeedback(feedback); | ||
``` | ||
```kotlin | ||
import io.sentry.Sentry | ||
import io.sentry.protocol.Feedback | ||
|
||
val feedback = Feedback("I encountered a bug while using the app.") | ||
feedback.name = "John Doe" | ||
feedback.contactEmail = "[email protected]" | ||
Sentry.captureFeedback(feedback) | ||
``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,63 @@ | ||
--- | ||
title: Set Up User Feedback | ||
sidebar_title: User Feedback | ||
description: "Learn more about collecting user feedback when an event occurs. Sentry pairs the feedback with the original event, giving you additional insight into issues." | ||
description: "Learn how to enable User Feedback in your Android app." | ||
sidebar_order: 6000 | ||
--- | ||
|
||
When a user experiences an error, Sentry provides the ability to collect additional feedback. You can collect feedback according to the method supported by the SDK. | ||
The User Feedback feature allows you to collect user feedback from anywhere inside your application at any time, without needing an error event to occur first. | ||
|
||
<Alert> | ||
If you're using a self-hosted Sentry instance, you'll need to be on version 24.4.2 or higher in order to use the full functionality of the User Feedback feature. Lower versions may have limited functionality. | ||
Ensure you are using the Android SDK version 8.13.0 or above of the SDK to access the latest features. | ||
</Alert> | ||
|
||
## User Feedback Widget | ||
|
||
The User Feedback widget allows users to submit feedback from anywhere inside your application. | ||
|
||
### Set Up | ||
|
||
To start using the User Feedback widget in your Android application, just start the SDK. | ||
A `SentryUserFeedbackDialog` will be available to be used in your app. | ||
For the configuration options, please refer to the <PlatformLink to="/user-feedback/configuration/">User Feedback Widget Configuration</PlatformLink>. | ||
|
||
```java | ||
import io.sentry.android.core.SentryUserFeedbackDialog; | ||
|
||
// Just instantiate the dialog and show it whenever you want | ||
new SentryUserFeedbackDialog(context).show(); | ||
``` | ||
```kotlin | ||
import io.sentry.android.core.SentryUserFeedbackDialog | ||
|
||
// Just instantiate the dialog and show it whenever you want | ||
SentryUserFeedbackDialog(context).show() | ||
``` | ||
|
||
### Session Replay | ||
|
||
The User Feedback widget integrates seamlessly with Session Replay. When the widget is opened, the SDK buffers up to 30 seconds of the user's session. If feedback is submitted, this replay is sent along with the feedback, allowing you to view both the feedback and the user's actions leading up to the feedback submission. | ||
|
||
## User Feedback API | ||
|
||
The user feedback API allows you to collect user feedback while utilizing your own UI. You can use the same programming language you have in your app to send user feedback. In this case, the SDK creates the HTTP request so you don't have to deal with posting data via HTTP. | ||
The User Feedback API allows you to collect user feedback while using your own UI components. You can submit feedback directly using the `Sentry.captureFeedback(Feedback)` method: | ||
|
||
```java | ||
import io.sentry.Sentry; | ||
import io.sentry.protocol.Feedback; | ||
|
||
Sentry pairs the feedback with the original event, giving you additional insight into issues. Sentry needs the `eventId` to be able to associate the user feedback to the corresponding event. For example, to get the `eventId`, you can use <PlatformLink to="/configuration/options/#before-send"><PlatformIdentifier name="before-send" /></PlatformLink> or the return value of the method capturing an event. | ||
Feedback feedback = new Feedback("I encountered a bug while using the app."); | ||
feedback.setName("John Doe"); | ||
feedback.setContactEmail("[email protected]"); | ||
Sentry.captureFeedback(feedback); | ||
``` | ||
```kotlin | ||
import io.sentry.Sentry | ||
import io.sentry.protocol.Feedback | ||
|
||
<PlatformContent includePath="user-feedback/sdk-api-example/" /> | ||
val feedback = Feedback("I encountered a bug while using the app.") | ||
feedback.name = "John Doe" | ||
feedback.contactEmail = "[email protected]" | ||
Sentry.captureFeedback(feedback) | ||
``` |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the tables 👍
we should use those more often in docs where it makes sense 🤔