[APP-1787] Some analytics cleanup (#9736)

* Clean up flags

* Move getMetadataForLogger

* Nail down attributers

* Polyfill features cache
This commit is contained in:
Eric Bailey
2026-01-22 16:57:59 -06:00
committed by GitHub
parent 6534630d16
commit df89b79c2a
9 changed files with 72 additions and 39 deletions
+38 -11
View File
@@ -1,10 +1,26 @@
import {MMKV} from '@bsky.app/react-native-mmkv'
import {setPolyfills} from '@growthbook/growthbook'
import {GrowthBook} from '@growthbook/growthbook-react'
import {type Metadata} from '#/analytics/metadata'
import {getNavigationMetadata, type Metadata} from '#/analytics/metadata'
import * as env from '#/env'
export {Features} from '#/analytics/features/types'
const CACHE = new MMKV({id: 'bsky_features_cache'})
setPolyfills({
localStorage: {
getItem: key => {
const value = CACHE.getString(key)
return value != null ? JSON.parse(value) : null
},
setItem: async (key, value) => {
CACHE.set(key, JSON.stringify(value))
},
},
})
/**
* We vary the amount of time we wait for GrowthBook to fetch feature
* gates based on the strategy specified.
@@ -46,17 +62,28 @@ export async function refresh({strategy}: {strategy: FeatureFetchStrategy}) {
}
/**
* Converts our metadata into GrowthBook attributes and sets them.
* Converts our metadata into GrowthBook attributes and sets them. GrowthBook
* attributes are manually configured in the GrowthBook dashboard. So these
* values need to match exactly. Therefore, let's add them here manually to and
* not spread them to avoid mistakes.
*/
export function setAttributes({base, session, preferences}: Metadata) {
const {deviceId, sessionId, ...br} = base
export function setAttributes({
base,
geolocation,
session,
preferences,
}: Metadata) {
features.setAttributes({
device_id: deviceId, // GrowthBook special field
session_id: sessionId, // GrowthBook special field
user_id: session?.did, // GrowthBook special field
id: session?.did, // GrowthBook special field
...br,
...(session || {}),
...(preferences || {}),
deviceId: base.deviceId,
sessionId: base.sessionId,
platform: base.platform,
appVersion: base.appVersion,
countryCode: geolocation.countryCode,
regionCode: geolocation.regionCode,
did: session?.did,
isBskyPds: session?.isBskyPds,
appLanguage: preferences?.appLanguage,
contentLanguages: preferences?.contentLanguages,
currentScreen: getNavigationMetadata()?.currentScreen,
})
}
+10 -5
View File
@@ -1,7 +1,12 @@
export enum Features {
DebugFeedContext = 'debug_show_feedcontext',
IsBskyTeam = 'is_bsky_team_member',
DisableOnboardingFindContacts = 'disable_onboarding_find_contacts',
DisableSettingsFindContacts = 'disable_settings_find_contacts',
DisableLiveNowBeta = 'disable_live_now_beta',
// core flags
IsBskyTeam = 'is_bsky_team',
// debug flags
DebugFeedContext = 'debug_feed_context',
// feature flags
ImportContactsOnboardingDisable = 'import_contacts:onboarding:disable',
ImportContactsSettingsDisable = 'import_contacts:settings:disable',
LiveNowBetaDisable = 'live_now_beta:disable',
}
+1 -1
View File
@@ -16,13 +16,13 @@ import {
useSessionId,
} from '#/analytics/identifiers'
import {
getMetadataForLogger,
getNavigationMetadata,
type MergeableMetadata,
type Metadata,
} from '#/analytics/metadata'
import {type Metrics, metrics} from '#/analytics/metrics'
import * as refParams from '#/analytics/misc/refParams'
import {getMetadataForLogger} from '#/analytics/utils'
import * as env from '#/env'
import {useGeolocation} from '#/geolocation'
import {device} from '#/storage'
+19 -1
View File
@@ -53,9 +53,27 @@ export type NavigationMetadata = {
}
let navigationMetadata: NavigationMetadata | undefined
export function getNavigationMetadata() {
console.log('metadata', JSON.stringify(navigationMetadata, null, 2))
return navigationMetadata
}
export function setNavigationMetadata(meta: NavigationMetadata | undefined) {
navigationMetadata = meta
}
/**
* We don't want or need to send all data to the logger
*/
export function getMetadataForLogger({
base,
geolocation,
session,
}: Metadata): Record<string, any> {
return {
deviceId: base.deviceId,
sessionId: base.sessionId,
platform: base.platform,
appVersion: base.appVersion,
countryCode: geolocation.countryCode,
regionCode: geolocation.regionCode,
isBskyPds: session?.isBskyPds || 'anonymous',
}
}
-17
View File
@@ -4,7 +4,6 @@ import {BSKY_SERVICE} from '#/lib/constants'
import {type SessionAccount} from '#/state/session'
import {
type MergeableMetadata,
type Metadata,
type SessionMetadata,
} from '#/analytics/metadata'
@@ -32,19 +31,3 @@ export function accountToSessionMetadata(
}
}
}
export function getMetadataForLogger({
base,
geolocation,
session,
}: Metadata): Record<string, any> {
return {
deviceId: base.deviceId,
sessionId: base.sessionId,
platform: base.platform,
appVersion: base.appVersion,
countryCode: geolocation.countryCode,
regionCode: geolocation.regionCode,
isBskyPds: session?.isBskyPds || 'anonymous',
}
}
@@ -24,7 +24,7 @@ export const enabled = createIsEnabledCheck(props => {
'2026-01-16T00:00:00.000Z',
props.currentProfile.createdAt,
) &&
!props.features.enabled(props.features.DisableLiveNowBeta)
!props.features.enabled(props.features.LiveNowBetaDisable)
)
})
+1 -1
View File
@@ -48,7 +48,7 @@ export function Onboarding() {
ENV !== 'e2e' &&
IS_NATIVE &&
findContactsEnabled &&
!ax.features.enabled(ax.features.DisableOnboardingFindContacts)
!ax.features.enabled(ax.features.ImportContactsOnboardingDisable)
const [state, dispatch] = useReducer(
reducer,
+1 -1
View File
@@ -213,7 +213,7 @@ export function SettingsScreen({}: Props) {
</SettingsList.LinkItem>
{IS_NATIVE &&
findContactsEnabled &&
!ax.features.enabled(ax.features.DisableSettingsFindContacts) && (
!ax.features.enabled(ax.features.ImportContactsSettingsDisable) && (
<SettingsList.LinkItem
to="/settings/find-contacts"
label={_(msg`Find friends from contacts`)}>
+1 -1
View File
@@ -106,7 +106,7 @@ export function useCanGoLive() {
const ax = useAnalytics()
const {hasSession} = useSession()
if (!hasSession) return false
return IS_DEV ? true : !ax.features.enabled(ax.features.DisableLiveNowBeta)
return IS_DEV ? true : !ax.features.enabled(ax.features.LiveNowBetaDisable)
}
export function useCheckEmailConfirmed() {