Product Hydration

Introduction

Product hydration lets you update product information at runtime before it is displayed to the user. This is useful for syncing prices, availability, descriptions, and variants with your own backend.

The Firework SDK supports two hydration modes:

Mode
Trigger
Scope
Listener

Video-level

A video or ivestream with products starts playing

Products from a single video/livestream

setOnProductHydrationListener

Feed-level

A page of feed data is loaded

Products aggregated from all videos in the page

setOnFeedProductHydrationListener

Both modes use the same ProductHydrator API to modify products. The sections below explain each mode and the full hydration API.


Hydration Level

Feed-Level Product Hydration

Note: Feed-level hydration currently only supports short videos. Livestream content is not supported.

Feed-level hydration batches all products from a loaded page of feed data into a single callback, instead of issuing one callback per video. Products are aggregated across all videos in the page and deduplicated by product ID.

This is the recommended approach for feed views (e.g. FwPlayerDeckView) where multiple videos are loaded at once, as it reduces the number of hydration requests from N (one per video) to 1 (one per page).

Setup

Register the listener via FireworkSdk.shopping.setOnFeedProductHydrationListener:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        FireworkSdk.shopping.setOnFeedProductHydrationListener { products, hydrator ->
            // Fetch latest product data from your backend
            val updatedProducts = myApi.fetchProducts(products.mapNotNull { it.id })

            for (product in products) {
                val productId = product.id ?: continue
                val updated = updatedProducts[productId] ?: continue
                hydrator.hydrate(productId) {
                    name(updated.name)
                    description(updated.description)
                    isAvailable(updated.inStock)
                    for (unit in product.units) {
                        val unitId = unit.id ?: continue
                        variant(unitId) {
                            price(updated.variants[unitId]?.price ?: 0.0)
                        }
                    }
                    this
                }
            }
            hydrator.completeHydration()
        }
    }

    override fun onDestroy() {
        FireworkSdk.shopping.setOnFeedProductHydrationListener(null)
        super.onDestroy()
    }
}

Callback Parameters

Parameter
Type
Description

products

List<Product>

Aggregated and deduplicated products from all videos in the loaded page.

hydrator

ProductHydrator

Builder used to modify product fields. Same API as video-level hydration.

Unlike video-level hydration, the callback does not include a videoInfo parameter because the products span multiple videos.

You must call hydrator.completeHydration() when finished. Without this call, updated values will not be applied.

Behavior

  • Applies to all view types: Feed-level hydration is a global listener. Once set, it takes effect for all SDK view components (FwPlayerDeckView, FwVideoFeedView, FwStoryBlockView).

  • Automatic per-item disabling (DeckView inline only): When a feed-level listener is set, per-item hydration is automatically disabled only for FwPlayerDeckView inline cards. It does not disable per-item hydration for fullscreen playback (whether launched from FwPlayerDeckView or FwVideoFeedView) or FwStoryBlockView.

  • Coexistence: Setting both setOnFeedProductHydrationListener and setOnProductHydrationListener at the same time is technically supported. If both are set, feed-level handles DeckView inline hydration while video-level handles fullscreen and StoryBlock. However, this is not recommended — see Best Practices below.

  • Timeout: The SDK waits up to 10 seconds for completeHydration() to be called. If the timeout is exceeded or an exception occurs, the original (non-hydrated) products are displayed.

  • Pagination: Each page load triggers a separate hydration callback. Products that were already hydrated in a previous page are not requested again.


Video-Level Product Hydration

Video-level hydration is triggered each time a video with associated products starts playing. The SDK calls your listener with the products for that specific video.

Register the listener via FireworkSdk.shopping.setOnProductHydrationListener:

Callback Parameters

Parameter
Type
Description

products

List<Product>

Products associated with the video that is about to play.

hydrator

ProductHydrator

Builder used to modify product fields.

videoInfo

VideoInfo

Information about the video that requested hydration.

You must call hydrator.completeHydration() when finished. Without this call, updated values will not be applied.

All code examples below only show the hydrate {} block for brevity. Refer to the example above for the full listener setup pattern. Remember to always call hydrator.completeHydration() after all hydrations are done.

Best Practices

For the simplest and most predictable integration, set only one hydration listener — either feed-level or video-level — rather than both.

Recommendation
When to use

Feed-level only (setOnFeedProductHydrationListener)

Your app uses FwPlayerDeckView and you want to reduce hydration requests from N-per-page to 1-per-page.

Video-level only (setOnProductHydrationListener)

You need per-video videoInfo in the callback, or your app primarily uses video and also livestream.

Setting a single listener avoids confusion about which listener handles which context, simplifies debugging, and ensures consistent hydration logic across all surfaces.


Product Hydration

Use ProductBuilder methods inside the hydrate {} block to modify product-level properties. These methods apply to both video-level and feed-level hydration.

Basic Attributes

Method
Description

name(name: String)

Sets or updates the product name.

description(description: String)

Sets or updates the product description.

subtitle(subtitle: String?)

Sets or updates the product subtitle. Pass null to clear.

currency(currency: String)

Sets the product-level currency code string (e.g. "USD", "EUR").

isAvailable(isAvailable: Boolean)

Sets the availability status of the product.

Main Product Image

Method
Description

mainProductImage(url: String)

Sets or updates the main product image URL. If a main image already exists, updates its URL; otherwise creates a new image entry.

Display Control

Method
Description

isDisabled(isDisabled: Boolean)

Sets the disabled status of the product. A disabled product is treated as unavailable.

hidePrice(hidePrice: Boolean)

Controls whether the product price is hidden from display.

hidden(hidden: Boolean?)

Sets whether the product should be hidden entirely. Pass null to use the default behavior.

CTA (Call-To-Action) Customization

Method
Description

customCTATitle(title: String?)

Sets a custom CTA button title. Pass null to clear.

customCTATitleTranslation(title: String?)

Sets a translated CTA title for localization. Pass null to clear.

customCTAUrl(url: String?)

Sets the URL the CTA button links to. Pass null to clear.

customCTATarget(target: String?)

Sets the CTA target identifier. Pass null to clear.

hidePrimaryCTA(hide: Boolean?)

Controls whether the primary CTA button is hidden. Pass null to use the default.


Variant Management

Add a new variant

Appends a new variant to the existing list of product variants. Image management is handled automatically.

Remove a variant

Removes a variant by its unique identifier. If the variant has an associated image, the image is also removed from the product's image lists.

Clear all existing variants

Removes all variants from the product, including their associated images.

You must add at least one variant after clearing all existing variants.

Replace existing variants with new variants

Replaces the entire set of variants at once. This clears existing variants internally and sets the new list, which is useful for refreshing variant offerings.

Modify existing variants

Locates a variant by its unique identifier and applies modifications through a ProductVariantBuilder block. If no variant with the given ID is found, the call is a no-op.


Important Notes

allowedVariantOptions

Sets the list of attribute names that are permissible for product variants. This ensures that all product variants conform to the expected attributes such as color, size, material, etc.

Call this method before adding new variants when using clearVariants() or replaceVariants() to ensure compatibility.

completeHydration()

Must be called after all hydrate() calls are finished. Without this call, the SDK will not apply any hydrated values.


API Reference

Last updated

Was this helpful?