Enable wishlist-item-removed signals in an Android app

The wishlist-item-removed signal fires when a user removes a product from their wishlist or list of saved items. Use this signal to track changes in saved product lists, compare wishlist adds and removes and identify patterns in how contacts manage their saved items.

Availability: Pro, Premium and Ultimate

Languages: Kotlin and Java


Implementation considerations

When to fire the signal

Decide when to send the signal based on your app's behavior:

  • On tap - fire as soon as the user taps to remove or un-save the item. Captures intent even if the action fails.
  • After confirmation - fire after confirming the item was removed. Ensures accuracy but may miss failed attempts.

For most implementations, firing on tap is recommended.

Multiple removal flows

Users can remove items from a favorites list from different screens in your app:

  • Product detail screen - tapping a filled heart button to un-save
  • Favorites or saved items screen - a dedicated remove button per item
  • Product listing - an un-save icon on a product card

Each screen may have access to different amounts of product data. Make sure all flows are covered and fire one signal per item - including when a user clears all favorites at once.

Contact mapping

Use the audience field to map this signal to a contact in Connect. Commonly used identifiers are email address, phone number and customer ID.

📘

Note

A customer ID mapped to the Contact key attribute in Connect is the most reliable identifier for known contacts. However, if no matching contact exists and the only attribute is a contact key, the signal is discarded - contact keys alone cannot create new contacts.

We recommend attaching identifiers to as many signals as possible. If the user is not authenticated, omit audience - Connect will attempt to identify the visitor using other signals from the same session.


Configuration

Method

Connect.logSignal(data: HashMap<String?, Any?>?): Boolean

Sends the signal to the Acoustic Connect endpoint. The Connect SDK must be initialized via Connect.enable() before calling this method.

Pass all fields as a flat HashMap. The SDK handles the signal structure automatically - you do not need to construct a nested object.

Signal fields

Required

FieldSchema typeDescription
productIdStringUnique product identifier. If missing, the signal is discarded.
signalTypeStringSignal type. Value: "wishlistItemRemoved".

Optional

FieldSchema typeDescription
audienceJSONObjectKey-value pairs for contact mapping. Must be a flat JSONObject - not a HashMap. Keys must match contact attribute names exactly as they appear in Connect.
categoryStringSignal category. Value: "Behavior".
currencyStringISO 4217 currency code (for example, "USD", "EUR"). Defaults to the currency set for your Connect subscription.
descriptionStringA description of the signal.
effectStringDescribes the effect of the signal on engagement.
externalVariantIdStringIdentifier for the specific product variant removed, such as a size or color.
nameStringA label to differentiate this signal from others (for example, "wishlistItemRemoved from favorites screen"). Max 256 characters.
priceNumberPrice of the product at the time it was removed. Pass as a string (for example, price.toPlainString()).
productCategoryStringCategory or department the product belongs to.
productNameStringDisplay name of the product.
wishlistIdStringIdentifier for the specific wishlist the item was removed from, useful if a contact can maintain more than one list.

Things to know

  • price has schema type Number but must be passed as a string - use price.toPlainString(). The SDK serializer silently drops numeric values.

  • Pass audience as a JSONObject, not a HashMap. A HashMap value is silently dropped by the SDK serializer and the contact will not be mapped.

  • Capture product data before the removal action - after removal the product may no longer be easily accessible.

  • Optional fields enhance the signal but do not prevent processing if omitted.

Required import

import org.json.JSONObject

Basic example

val data = hashMapOf<String?, Any?>(
    "signalType" to "wishlistItemRemoved",
    "productId" to "SKU-12345",
    "productName" to "Linen Throw",
    "price" to "89.99",
    "currency" to "USD"
)
Connect.logSignal(data)

Complete example

This example fires a wishlist item removed signal when the user taps a filled heart button to un-save the product. The signal fires only when the item is being removed, determined by the return value of the toggle function.

import org.json.JSONObject
import com.acoustic.connect.android.connectmod.Connect

private fun toggleWishlist(product: Product) {
    val isNowFaved = FavoritesStore.toggle(product.id)

    if (!isNowFaved) {
        // Item was just removed from favorites
        val data = hashMapOf<String?, Any?>(
            "signalType" to "wishlistItemRemoved",
            "productId" to product.id,
            "productName" to product.name,
            "price" to product.price.toPlainString(),
            "productCategory" to product.categoryName,
            "currency" to "USD",
            "category" to "Behavior",
            "name" to "wishlistItemRemoved from product detail"
        )

        // audience must be JSONObject - HashMap values are silently dropped
        UserSession.email?.let { email ->
            data["audience"] = JSONObject().put("Email Address", email)
        }

        Connect.logSignal(data)
    }
}

Troubleshooting

Signal not appearing in Connect?

  • Confirm Connect.enable() is called before logSignal.
  • Capture the return value and check that it is true: val accepted = Connect.logSignal(data). A false return indicates the SDK rejected the call - no additional configuration is required to use the return value.
  • Confirm productId is present - it is required and its absence discards the entire signal.
  • Verify the appKey and postMessageUrl match the Connect org you're checking.

Contact not created or updated?

  • Confirm audience is a JSONObject, not a HashMap.
  • Verify attribute key names match exactly how they appear in Connect - including capitalization and spacing.

Related pages


Did this page help you?