Skip to main content

Facilities

The Facilities module manages the locations associated with the authenticated member -- gyms, partner sites, and other supported venues. Use it to load the member's facility list, verify or remove locations, enable geofence-based visit monitoring, and submit nominations for new facilities.


Data Model

Facility

FieldTypeDescription
facilityIdInt?Unique facility identifier.
nameString?Display name of the facility.
addressString?Street address.
cityString?City.
stateString?Two-letter state code.
zipCodeString?Postal code.
latitudeDouble?Geographic latitude.
longitudeDouble?Geographic longitude.
verifiedBoolean?Whether the member has confirmed this facility.

Get Facilities

Retrieve all facilities currently associated with the member. This includes verified, pending, and blacklisted locations.

lifecycleScope.launch {
try {
val facilities = AFCore.facilities().get()
facilitiesAdapter.submitList(facilities.filterNotNull())
} catch (e: Exception) {
showError("Could not load facilities: ${e.message}")
}
}

Verify or Blacklist a Facility

Update the verification status of a facility. Pass verified: true to confirm a location, or verified: false to blacklist it. This also works for facilities discovered through the Map search -- calling update on a facility not yet in the member's list will add it.

lifecycleScope.launch {
val result = AFCore.facilities().update(facilityId = 12345, verified = true)
if (result.status) {
showSuccess("Facility verified")
refreshFacilities()
} else {
showError("Update failed: ${result.statusMessage}")
}
}

Delete a Facility

Remove a facility from the member's list. This permanently detaches the location from their account.

lifecycleScope.launch {
val result = AFCore.facilities().delete(facilityId = 12345)
if (result.status) {
removeFromList(12345)
} else {
showError("Could not remove facility: ${result.statusMessage}")
}
}

Nominate a Facility

Submit a new facility that is not yet part of the network. Use this when a member visits a gym or location that the system does not recognize.

Parameters

ParameterTypeRequiredDescription
clubNameStringYesName of the facility.
address1StringYesPrimary street address.
address2String?NoSuite, unit, or apartment number.
cityStringYesCity.
stateCodeStringYesTwo-letter state code.
zipCodeStringYesPostal or ZIP code.
latitudeDouble?NoGeographic latitude.
longitudeDouble?NoGeographic longitude.
phoneNumberString?NoContact phone number.
emailString?NoContact email address.
managerNameString?NoFacility manager's name.
currentlyAMemberBooleanNoWhether the member belongs to this facility.
metadataMap<String, String>?NoAdditional key-value pairs (see below).

Metadata Keys

KeyDescription
websiteCanonical website URL.
googlePlaceIdGoogle Places ID for programmatic verification.
yelpIdYelp business identifier.
foursquareIdFoursquare venue identifier.
sourceOrigin of the nomination (e.g., "ios-app", "android-app").

Including provider IDs makes backend verification and deduplication more reliable than free-text matching alone.

lifecycleScope.launch {
try {
val result = AFCore.facilities().nominateFacility(
clubName = "Downtown Fitness",
address1 = "123 Main St",
address2 = null,
city = "Springfield",
stateCode = "CA",
zipCode = "90210",
latitude = 34.052235,
longitude = -118.243683,
phoneNumber = "(555) 123-4567",
email = "info@downtownfitness.example",
managerName = "Jane Doe",
currentlyAMember = true,
metadata = mapOf(
"googlePlaceId" to "ChIJN1t_tDeuEmsRUsoyG83frY4",
"source" to "android-app"
)
)

if (result.status) {
showSuccess("Nomination submitted")
} else {
showError("Nomination failed: ${result.statusMessage}")
}
} catch (e: Exception) {
showError("Could not submit nomination: ${e.message}")
}
}

Geofence Monitoring

Enable or disable geofence-based monitoring for the member's verified facilities. When active, the SDK tracks proximity and detects visits automatically. Use subscribeToEvents() to receive real-time geofence events (see Gym Visits for full details).

Start monitoring after login or onboarding. Stop monitoring on logout or when background location tracking is no longer needed.

Start Monitoring

// Android
lifecycleScope.launch {
val started = AFCore.facilities().startMonitoring()
if (started) {
Log.d("Facilities", "Geofence monitoring active")
}
}

Stop Monitoring

// Android
val stopped = AFCore.facilities().stopMonitoring()

Check Monitoring Status

// Android
val active = AFCore.facilities().isMonitoringActive()

Best Practices

  • Cache facilities locally and refresh when the member opens the facilities screen or pulls to refresh.
  • Show a confirmation dialog before deleting a facility, since the operation is permanent.
  • Use optimistic UI updates when verifying or blacklisting -- update the local list immediately and revert if the API call fails.
  • Validate nomination inputs client-side before submitting. Require at minimum: club name, address, city, state, and ZIP code.

Quick Reference

// Android
AFCore.facilities().get()
AFCore.facilities().update(facilityId, verified)
AFCore.facilities().delete(facilityId)
AFCore.facilities().nominateFacility(clubName, address1, address2, city, stateCode, zipCode, ...)
AFCore.facilities().getNominatedFacilities()
AFCore.facilities().startMonitoring()
AFCore.facilities().stopMonitoring()
AFCore.facilities().isMonitoringActive()
AFCore.facilities().subscribeToEvents(onEvent, onError)