Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat(Mobile): add firebase integrations and bootstrap usage #4787

Closed
wants to merge 55 commits into from
Closed
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
50d236d
add packages & expo configs
Jonathansoufer Jan 15, 2025
b99cf4e
adds/updates git|eas ignore files
Jonathansoufer Jan 16, 2025
aeaf23d
adds a central place to host all notification interactions
Jonathansoufer Jan 16, 2025
8d6abdd
adds Notifications context
Jonathansoufer Jan 16, 2025
c2f3498
adds package
Jonathansoufer Jan 16, 2025
905ad7f
adds Notification initialization
Jonathansoufer Jan 16, 2025
ae3b083
adds task manager to handle bg notifications
Jonathansoufer Jan 16, 2025
559cb88
adds initializer func
Jonathansoufer Jan 16, 2025
4d6619a
initialize notifications service
Jonathansoufer Jan 16, 2025
a682907
fix build proccess on eas
Jonathansoufer Jan 17, 2025
8d1941b
remove/add packages necessary
Jonathansoufer Jan 20, 2025
140610c
adjust eas building for android
Jonathansoufer Jan 20, 2025
f2634af
change context by hook pattern
Jonathansoufer Jan 21, 2025
81f7993
change context by hook pattern
Jonathansoufer Jan 21, 2025
75fc547
add initial notification slice
Jonathansoufer Jan 21, 2025
618b593
remove context
Jonathansoufer Jan 21, 2025
5ddf6f3
add initial notification slice
Jonathansoufer Jan 21, 2025
c12face
add notifications utils and constants
Jonathansoufer Jan 21, 2025
17de513
add notifications hook
Jonathansoufer Jan 21, 2025
38302ba
add firebase config
Jonathansoufer Jan 21, 2025
352a95b
simplify services
Jonathansoufer Jan 21, 2025
8c55da9
add some final touches
Jonathansoufer Jan 22, 2025
490e9b6
add (temp) local trigger
Jonathansoufer Jan 22, 2025
8a5712c
adds missing expo config
Jonathansoufer Jan 23, 2025
448edcd
refactor permission request
Jonathansoufer Jan 23, 2025
d733f27
add (temp) local useEffect trigger
Jonathansoufer Jan 23, 2025
85cdbf9
removes (temp) local useEffect trigger
Jonathansoufer Jan 23, 2025
f8aa2b9
first round of review fixes
Jonathansoufer Jan 23, 2025
31ad4c7
addresses secondfirst round of review fixes
Jonathansoufer Jan 23, 2025
425b027
refactor: wrap sensitive calls in try/catch
Jonathansoufer Jan 23, 2025
a364776
refactor: makes usage of regular class
Jonathansoufer Jan 23, 2025
37e736a
Tests: Update cypress tests (#4777)
mike10ca Jan 15, 2025
5a94075
Refactor(Tx speed up): rm unused argument (#4778)
katspaugh Jan 15, 2025
e96084f
Tests: Update cy tests (#4780)
mike10ca Jan 15, 2025
cda9cde
refactor(web): use new gateway RTK API (#4752)
compojoom Jan 16, 2025
732bd41
Fix(Tx notes): hide for 1/X safes (#4785)
katspaugh Jan 16, 2025
3ee78d1
1.49.3
katspaugh Jan 16, 2025
33c67d0
Docs: fix md syntax in README.md
katspaugh Jan 16, 2025
1a79e81
fix: Enable Add proposer button for owners only (#4744)
usame-algan Jan 17, 2025
6a04547
Chore(deps-dev): Bump @eslint/js from 9.16.0 to 9.18.0 (#4792)
dependabot[bot] Jan 20, 2025
39f49b2
Chore(deps): Bump react-native-reanimated from 3.16.3 to 3.16.7 (#4796)
dependabot[bot] Jan 20, 2025
1f76f79
Chore(deps): Bump @tamagui/babel-plugin from 1.120.2 to 1.121.12 (#4793)
dependabot[bot] Jan 20, 2025
e4f80ab
Refactor(Tx decoding): use transaction preview endpoint (#4783)
katspaugh Jan 20, 2025
578fd18
Tests: Improve test organization (#4798)
mike10ca Jan 20, 2025
7eb2fc0
Fix(Swaps): TWAP order decoding (#4803)
katspaugh Jan 21, 2025
eda1be4
fix(Swaps): deprecate `executedSurplusFee` (#4763)
iamacook Jan 21, 2025
cd102eb
fix(Relay): revert mandatory estimation of `gasLimit` (#4801)
iamacook Jan 21, 2025
aa2e16d
Chore: add public/*.js to gitignore
katspaugh Jan 21, 2025
499e005
Chore(deps): Bump undici from 6.21.0 to 6.21.1 in the npm_and_yarn gr…
dependabot[bot] Jan 22, 2025
700438a
Fix(Indexing status): poll every minute (#4806)
katspaugh Jan 22, 2025
d8994a7
Fix(TWAP): executedFee can be undefined (#4817)
katspaugh Jan 23, 2025
68dea6d
Docs: update bug-report.md
katspaugh Jan 23, 2025
46eea1d
Fix(Blockaid): pass chain id instead of chain name for Blast and othe…
katspaugh Jan 23, 2025
68965f4
fix: merge conflicts
Jonathansoufer Jan 23, 2025
ac1f289
adds package
Jonathansoufer Jan 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions apps/mobile/.easignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Auto generated storybook file
.storybook/storybook.requires.ts

# From jest
html
coverage

# macOS
.DS_Store

/.idea
# Tamagui UI generates a lot of cache files
.tamagui

*storybook.log
/storybook-static

# Android and iOS build files
/android/*
/ios/*

# @generated expo-cli sync-8d4afeec25ea8a192358fae2f8e2fc766bdce4ec
# The following patterns were generated by expo-cli

# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files

# dependencies
node_modules/

# Expo
.expo/
dist/
web-build/
expo-env.d.ts

# Native
*.orig.*
*.
*.jks
*.p8
*.p12
*.key
*.mobileprovision

# Metro
.metro-health-check*

# debug
npm-debug.*
yarn-debug.*
yarn-error.*

# macOS
.DS_Store
*.pem

# local env files
.env*.local

# typescript
*.tsbuildinfo

# @end expo-cli
2 changes: 2 additions & 0 deletions apps/mobile/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ coverage
# Android and iOS build files
/android/*
/ios/*
google-services.json
GoogleService-Info.plist

# @generated expo-cli sync-8d4afeec25ea8a192358fae2f8e2fc766bdce4ec
# The following patterns were generated by expo-cli
Expand Down
15 changes: 15 additions & 0 deletions apps/mobile/app.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ export default {
supportsTablet: true,
appleTeamId: 'MXRS32BBL4',
bundleIdentifier: IS_DEV ? 'global.safe.mobileapp.dev' : 'global.safe.mobileapp',
entitlements: {
'aps-environment': 'production',
},
googleServicesFile: process.env.GOOGLE_SERVICES_PLIST ?? './GoogleService-Info.plist',
},
android: {
adaptiveIcon: {
Expand All @@ -36,6 +40,7 @@ export default {
monochromeImage: './assets/images/monochrome-icon.png',
},
package: IS_DEV ? 'global.safe.mobileapp.dev' : 'global.safe.mobileapp',
googleServicesFile: process.env.GOOGLE_SERVICES_JSON ?? './google-services.json',
},
web: {
bundler: 'metro',
Expand Down Expand Up @@ -63,6 +68,16 @@ export default {
},
],
['./expo-plugins/withDrawableAssets.js', './assets/android/drawable'],
[
'expo-build-properties',
{
ios: {
useFrameworks: 'static',
},
},
],
'@react-native-firebase/app',
'@react-native-firebase/messaging',
],
experiments: {
typedRoutes: true,
Expand Down
80 changes: 43 additions & 37 deletions apps/mobile/app/_layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Stack } from 'expo-router'
import 'react-native-reanimated'

compojoom marked this conversation as resolved.
Show resolved Hide resolved
import { SafeThemeProvider } from '@/src/theme/provider/safeTheme'
import { Provider } from 'react-redux'
import { persistor, store } from '@/src/store'
Expand All @@ -14,8 +15,11 @@ import { SafeToastProvider } from '@/src/theme/provider/toastProvider'
import { configureReanimatedLogger, ReanimatedLogLevel } from 'react-native-reanimated'
import { OnboardingHeader } from '@/src/features/Onboarding/components/OnboardingHeader'
import { install } from 'react-native-quick-crypto'
import { NotificationProvider } from '@/src/context/NotificationContext'
import { initNotificationService } from '@/src/services/notifications/FCMService'

install()
initNotificationService()

configureReanimatedLogger({
level: ReanimatedLogLevel.warn,
Expand All @@ -28,43 +32,45 @@ function RootLayout() {
return (
<GestureHandlerRootView>
<Provider store={store}>
<PortalProvider shouldAddRootHost>
<BottomSheetModalProvider>
<PersistGate loading={null} persistor={persistor}>
<SafeThemeProvider>
<SafeToastProvider>
<Stack
screenOptions={({ navigation }) => ({
headerBackButtonDisplayMode: 'minimal',
headerShadowVisible: false,
headerLeft: (props) => (
<HeaderBackButton
{...props}
testID={'go-back'}
onPress={navigation.goBack}
displayMode={'minimal'}
/>
),
})}
>
<Stack.Screen
name="index"
options={{
header: OnboardingHeader,
}}
/>
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
<Stack.Screen name="pending-transactions" options={{ headerShown: true, title: '' }} />
<Stack.Screen name="signers" options={{ headerShown: true, title: 'Signers' }} />
<Stack.Screen name="notifications" options={{ headerShown: true, title: 'Notifications' }} />
<Stack.Screen name="app-settings" options={{ headerShown: true, title: 'Settings' }} />
<Stack.Screen name="+not-found" />
</Stack>
</SafeToastProvider>
</SafeThemeProvider>
</PersistGate>
</BottomSheetModalProvider>
</PortalProvider>
<NotificationProvider>
<PortalProvider shouldAddRootHost>
<BottomSheetModalProvider>
<PersistGate loading={null} persistor={persistor}>
<SafeThemeProvider>
<SafeToastProvider>
<Stack
screenOptions={({ navigation }) => ({
headerBackButtonDisplayMode: 'minimal',
headerShadowVisible: false,
headerLeft: (props) => (
<HeaderBackButton
{...props}
testID={'go-back'}
onPress={navigation.goBack}
displayMode={'minimal'}
/>
),
})}
>
<Stack.Screen
name="index"
options={{
header: OnboardingHeader,
}}
/>
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
<Stack.Screen name="pending-transactions" options={{ headerShown: true, title: '' }} />
<Stack.Screen name="signers" options={{ headerShown: true, title: 'Signers' }} />
<Stack.Screen name="notifications" options={{ headerShown: true, title: 'Notifications' }} />
<Stack.Screen name="app-settings" options={{ headerShown: true, title: 'Settings' }} />
<Stack.Screen name="+not-found" />
</Stack>
</SafeToastProvider>
</SafeThemeProvider>
</PersistGate>
</BottomSheetModalProvider>
</PortalProvider>
</NotificationProvider>
</Provider>
</GestureHandlerRootView>
)
Expand Down
10 changes: 10 additions & 0 deletions apps/mobile/eas.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@
"extends": "base",
"environment": "production",
"autoIncrement": true,
"ios": {
"env": {
"GOOGLE_SERVICES_FILE": "./GoogleService-Info.plist"
}
},
"android": {
"env": {
"GOOGLE_SERVICES_FILE": "./google-services.json"
}
},
"env": {
"APP_VARIANT": "production"
}
Expand Down
8 changes: 7 additions & 1 deletion apps/mobile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
"@expo/vector-icons": "^14.0.2",
"@react-native-clipboard/clipboard": "^1.15.0",
"@react-native-community/blur": "^4.4.1",
"@react-native-firebase/app": "^21.6.2",
"@react-native-firebase/messaging": "^21.6.2",
"@react-native-menu/menu": "^1.1.6",
"@react-native/babel-preset": "^0.76.2",
"@react-navigation/material-top-tabs": "^7.1.0",
Expand All @@ -64,16 +66,20 @@
"ethers": "^6.13.4",
"expo": "~52.0.14",
"expo-blur": "~14.0.1",
"expo-constants": "~17.0.2",
"expo-build-properties": "~0.13.2",
"expo-constants": "~17.0.4",
"expo-dev-client": "~5.0.5",
"expo-device": "~7.0.2",
"expo-font": "~13.0.3",
"expo-image": "~2.0.3",
"expo-linear-gradient": "^14.0.1",
"expo-linking": "~7.0.3",
"expo-notifications": "~0.29.12",
compojoom marked this conversation as resolved.
Show resolved Hide resolved
"expo-router": "~4.0.15",
"expo-splash-screen": "^0.29.16",
"expo-status-bar": "~2.0.0",
"expo-system-ui": "~4.0.6",
"expo-task-manager": "^12.0.4",
"expo-web-browser": "~14.0.1",
"lodash": "^4.17.21",
"moti": "^0.29.0",
Expand Down
68 changes: 68 additions & 0 deletions apps/mobile/src/context/NotificationContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React, { createContext, useContext, useState, useEffect, useRef, ReactNode } from 'react'
import * as Notifications from 'expo-notifications'
import { registerForPushNotificationsAsync } from '@/src/services/notifications/FCMService'

interface NotificationContextType {
expoPushToken: string | null
notification: Notifications.Notification | null
error: Error | null
}

const NotificationContext = createContext<NotificationContextType | undefined>(undefined)

export const useNotification = () => {
const context = useContext(NotificationContext)
if (context === undefined) {
throw new Error('useNotification must be used within a NotificationProvider')
}
return context
}

interface NotificationProviderProps {
children: ReactNode
}

export const NotificationProvider: React.FC<NotificationProviderProps> = ({ children }) => {
const [expoPushToken, setExpoPushToken] = useState<string | null>(null)
const [notification, setNotification] = useState<Notifications.Notification | null>(null)
const [error, setError] = useState<Error | null>(null)

const notificationListener = useRef<Notifications.EventSubscription>()
const responseListener = useRef<Notifications.EventSubscription>()

useEffect(() => {
registerForPushNotificationsAsync().then(
(token) => setExpoPushToken(token ?? null),
(error) => setError(error),
)

notificationListener.current = Notifications.addNotificationReceivedListener((notification) => {
console.log('🔔 Notification Received: ', notification)
setNotification(notification)
})

responseListener.current = Notifications.addNotificationResponseReceivedListener((response) => {
console.log(
'🔔 Notification Response: ',
JSON.stringify(response, null, 2),
JSON.stringify(response.notification.request.content.data, null, 2),
)
// Handle the notification response here after discussing with the Aaron
})

return () => {
if (notificationListener.current) {
Notifications.removeNotificationSubscription(notificationListener.current)
}
if (responseListener.current) {
Notifications.removeNotificationSubscription(responseListener.current)
}
}
}, [])

return (
<NotificationContext.Provider value={{ expoPushToken, notification, error }}>
{children}
</NotificationContext.Provider>
)
}
Loading
Loading