diff --git a/lib/utils/push-alerts.js b/lib/utils/push-alerts.js
--- a/lib/utils/push-alerts.js
+++ b/lib/utils/push-alerts.js
@@ -1,14 +1,30 @@
// @flow
import type { AlertInfo } from '../types/alert-types.js';
+import { isDev } from '../utils/dev-utils.js';
+import { usingCommServicesAccessToken } from '../utils/services-utils.js';
const msInDay = 24 * 60 * 60 * 1000;
-const shouldSkipPushPermissionAlert = (alertInfo: AlertInfo): boolean =>
- (alertInfo.totalAlerts > 3 &&
- alertInfo.lastAlertTime > Date.now() - msInDay) ||
- (alertInfo.totalAlerts > 6 &&
- alertInfo.lastAlertTime > Date.now() - msInDay * 3) ||
- (alertInfo.totalAlerts > 9 &&
- alertInfo.lastAlertTime > Date.now() - msInDay * 7);
-
-export { shouldSkipPushPermissionAlert };
+
+function shouldSkipPushPermissionAlert(alertInfo: AlertInfo): boolean {
+ return (
+ (alertInfo.totalAlerts > 3 &&
+ alertInfo.lastAlertTime > Date.now() - msInDay) ||
+ (alertInfo.totalAlerts > 6 &&
+ alertInfo.lastAlertTime > Date.now() - msInDay * 3) ||
+ (alertInfo.totalAlerts > 9 &&
+ alertInfo.lastAlertTime > Date.now() - msInDay * 7)
+ );
+}
+
+function shouldSkipConnectFarcasterAlert(alertInfo: AlertInfo): boolean {
+ // The isDev check is here so that devs don't get continually spammed
+ // with this alert.
+ return (
+ isDev ||
+ !usingCommServicesAccessToken ||
+ alertInfo.lastAlertTime > Date.now() - msInDay
+ );
+}
+
+export { shouldSkipPushPermissionAlert, shouldSkipConnectFarcasterAlert };
diff --git a/native/components/connect-farcaster-alert-handler.react.js b/native/components/connect-farcaster-alert-handler.react.js
new file mode 100644
--- /dev/null
+++ b/native/components/connect-farcaster-alert-handler.react.js
@@ -0,0 +1,69 @@
+// @flow
+
+import { useNavigation } from '@react-navigation/native';
+import * as React from 'react';
+
+import { recordAlertActionType } from 'lib/actions/alert-actions.js';
+import { FIDContext } from 'lib/components/fid-provider.react.js';
+import { cookieSelector } from 'lib/selectors/keyserver-selectors.js';
+import {
+ alertTypes,
+ type RecordAlertActionPayload,
+} from 'lib/types/alert-types.js';
+import { authoritativeKeyserverID } from 'lib/utils/authoritative-keyserver.js';
+import { shouldSkipConnectFarcasterAlert } from 'lib/utils/push-alerts.js';
+import { useDispatch } from 'lib/utils/redux-utils.js';
+import sleep from 'lib/utils/sleep.js';
+
+import { ConnectFarcasterBottomSheetRouteName } from '../navigation/route-names.js';
+import { useSelector } from '../redux/redux-utils.js';
+
+function ConnectFarcasterAlertHandler(): React.Node {
+ const { navigate } = useNavigation();
+
+ const isActive = useSelector(state => state.lifecycleState !== 'background');
+
+ const currentUserID = useSelector(state => state.currentUserInfo?.id);
+ const cookie = useSelector(cookieSelector(authoritativeKeyserverID()));
+ const hasUserCookie = !!(cookie && cookie.startsWith('user='));
+ const loggedIn = !!currentUserID && hasUserCookie;
+
+ const fid = React.useContext(FIDContext)?.fid;
+
+ const connectFarcasterAlertInfo = useSelector(
+ state => state.alertStore.alertInfos[alertTypes.CONNECT_FARCASTER],
+ );
+
+ const dispatch = useDispatch();
+
+ React.useEffect(() => {
+ if (
+ !loggedIn ||
+ !isActive ||
+ !!fid ||
+ shouldSkipConnectFarcasterAlert(connectFarcasterAlertInfo)
+ ) {
+ return;
+ }
+
+ void (async () => {
+ await sleep(1000);
+
+ navigate(ConnectFarcasterBottomSheetRouteName);
+
+ const payload: RecordAlertActionPayload = {
+ alertType: alertTypes.CONNECT_FARCASTER,
+ time: Date.now(),
+ };
+
+ dispatch({
+ type: recordAlertActionType,
+ payload,
+ });
+ })();
+ }, [connectFarcasterAlertInfo, dispatch, fid, isActive, loggedIn, navigate]);
+
+ return null;
+}
+
+export default ConnectFarcasterAlertHandler;
diff --git a/native/root.react.js b/native/root.react.js
--- a/native/root.react.js
+++ b/native/root.react.js
@@ -47,6 +47,7 @@
import ChatContextProvider from './chat/chat-context-provider.react.js';
import MessageEditingContextProvider from './chat/message-editing-context-provider.react.js';
import AccessTokenHandler from './components/access-token-handler.react.js';
+import ConnectFarcasterAlertHandler from './components/connect-farcaster-alert-handler.react.js';
import { FeatureFlagsProvider } from './components/feature-flags-provider.react.js';
import PersistedStateGate from './components/persisted-state-gate.js';
import ReportHandler from './components/report-handler.react.js';
@@ -298,6 +299,7 @@
+
);