Skip to main content

C. Searching SDK Authentications

The Entrupy Android SDK provides functionality to search for past authentications initiated by the currently authorized user. This allows you to build features like a submission history screen within your application.

Backend Search Alternative

If you need to search authentications across all users within your organization or require more complex server-side filtering and data aggregation, you should use the Entrupy API from your backend server. The SDK search is scoped to the logged-in SDK user.

To search for submissions, use the searchSubmissions method. This method supports pagination and filtering.

Key Parameters:

  • pageCursor: An array (often of strings or a specific cursor object type defined by the SDK) that determines which page of results to fetch. For the first page, pass an empty array or null as appropriate based on the SDK's exact method signature.
  • filters: An array of maps to filter search results. Each map typically contains a key (the field to filter on) and a value or values (the criteria).
  • startDate, endDate: Unix epoch timestamps (as Long) to filter submissions within a specific date range. Use 0 if a date boundary is not needed.
  • paginationLimit: An integer specifying the maximum number of items per page (e.g., 20). The maximum allowed by the SDK is typically 25.

Ensure your class implements the appropriate callback interface.

// Kotlin
import com.entrupy.sdk.EntrupySDK

// Ensure your class implements the appropriate callback interface
// class YourActivity : AppCompatActivity(), EntrupySearchCallback { ... }

class SubmissionSearchManager(private val callback: EntrupySearchCallback) {
private var nextPageCursor: List<Any>? = emptyList() // Store cursor for pagination. Type based on SDK.
private var isLoading = false
var allItemsLoaded = false

val perPage = 20

fun fetchInitialSubmissions(filters: List<Map<String, Any>> = emptyList(), startDate: Long = 0, endDate: Long = 0) {
nextPageCursor = emptyList() // Reset for a new initial search
allItemsLoaded = false
fetchNextPage(filters, startDate, endDate)
}

fun fetchNextPage(filters: List<Map<String, Any>> = emptyList(), startDate: Long = 0, endDate: Long = 0) {
if (isLoading || allItemsLoaded) {
if (isLoading) println("Search already in progress.")
if (allItemsLoaded) println("All items already loaded.")
return
}

if (!EntrupySDK.getInstance().isAuthorizationValid()) {
println("User not authorized. Cannot perform search.")
// Handle re-authorization if needed
// Potentially call a callback method to indicate auth error
return
}

isLoading = true

// The type for pageCursor (nextPageCursor) needs to match what the SDK expects.
// Casting to List<Any> if your nextPageCursor is, for example, List<String>. Adjust as needed.
val cursorForSDK = nextPageCursor ?: emptyList()

EntrupySDK.getInstance().searchSubmissions(
pageCursor = cursorForSDK,
filters = filters,
startDate = startDate,
endDate = endDate,
paginationLimit = perPage,
callback = callback
)
}

// Call this method from your callback's success method
fun searchCompletedSuccessfully(nextCursorFromSDK: List<Any>?) {
isLoading = false
this.nextPageCursor = nextCursorFromSDK
if (nextCursorFromSDK.isNullOrEmpty()) {
allItemsLoaded = true
println("All submissions loaded.")
}
}

// Call this method from your callback's failure method
fun searchFailed() {
isLoading = false
// Potentially allow retry
}
}

2. Search Filters

You can apply various filters to narrow down your search results.

Filtering by Brand(s):

// Filter by a single brand
val brandFilter = listOf(mapOf("key" to "properties.brand.id", "value" to "nike"))

// Filter by multiple brands
val multiBrandFilter = listOf(mapOf("key" to "properties.brand.id", "values" to listOf("nike", "adidas")))

Supported brand values: Refer to SDK documentation for a list of accepted brand ID strings (e.g., adidas, alexander_mcqueen, balenciaga).

Filtering by Result Type(s):

// Filter by a single result type
val resultFilter = listOf(mapOf("key" to "status.result.id", "value" to "authentic"))

// Filter by multiple result types
val multiResultFilter = listOf(mapOf("key" to "status.result.id", "values" to listOf("unknown", "authentic")))

Supported result values: authentic, unknown, not_supported, needs_review, invalid.

Filtering by Flag Status:

val flagFilter = listOf(mapOf("key" to "status.flag", "value" to "flagged"))

Supported flag values: none, flagged, resolved.

Filtering by Your customer_item_id:

// Assuming your customer_item_id was stored using the key "text_fields.sku"
val customerIdFilter = listOf(mapOf("key" to "text_fields.sku", "value" to "YOUR_UNIQUE_ITEM_ID_123"))
Key for customer_item_id

The exact filter key for customer_item_id (e.g., "text_fields.sku" or a more direct field like "customer_item_id") should be verified with the current SDK specifications.

Combining Filters (Cascading):

To apply multiple filter criteria, include multiple filter maps in the filters list:

val combinedFilter = listOf(
mapOf("key" to "properties.brand.id", "values" to listOf("nike", "adidas")),
mapOf("key" to "status.result.id", "value" to "authentic")
)

3. Handling Search Callback Methods

Implement the appropriate callback interface methods to process the search results or handle errors.

// Kotlin
// class YourActivity : AppCompatActivity(), EntrupySearchCallback {

override fun onSearchSubmissionsComplete(result: Map<String, Any>) {
// searchManager.searchCompletedSuccessfully(nextCursor) // Update your search manager
println("Search completed successfully.")
try {
// Assuming a data class EntrupySearchResult exists (as per SDK documentation)
// Adapt this based on the actual structure provided by the current SDK.
// data class EntrupySearchResult(
// val items: List<EntrupySearchedItem>, // Define EntrupySearchedItem based on SDK
// val next_cursor: List<Any>?
// )

// ---- Conceptual interpretation based on legacy structure ----
val items = result["items"] as? List<Map<String, Any>> ?: emptyList()
val nextCursor = result["next_cursor"] as? List<Any>
// ---- End conceptual interpretation ----

// Pass nextCursor to your SubmissionSearchManager or pagination handler
// submissionSearchManager.searchCompletedSuccessfully(nextCursor)

if (items.isNotEmpty()) {
println("Found ${items.size} items.")
// Process items: update your RecyclerView, ListView, or data models
// For example, append to a list and notify adapter
} else {
println("No items found for this page/filter.")
// Handle empty state if it's the first page
}

if (nextCursor.isNullOrEmpty()) {
println("This is the last page of results.")
// submissionSearchManager.allItemsLoaded = true (if using a manager)
// Disable further pagination calls
}

} catch (e: Exception) {
println("Error decoding search result: $e")
// submissionSearchManager.searchFailed() (if using a manager)
}
}

override fun onSearchSubmissionsError(errorCode: EntrupyErrorCode, description: String, localizedDescription: String) {
// searchManager.searchFailed() // Update your search manager
println("Search submissions failed. Error: $localizedDescription (Code: $errorCode)")
// Handle error: inform user, log, allow retry.
// Refer to Error Code Reference for specific error codes.
}
// }

By using the search functionality with appropriate filters and pagination, you can provide users with a comprehensive history of their authentications directly within your app.