From 215534d0c86e7960543f4885831caae4d90ad5c0 Mon Sep 17 00:00:00 2001 From: xmflsct Date: Mon, 9 Jan 2023 00:55:29 +0100 Subject: [PATCH] Fix #605 Turns out to be much more complicated than expected. Finally got the app running through Browser Stack (thanks for their sponsoring!), realised the issue was related to an early attempt to create a build for F-Droid #50 which removed the Google Service. However for Android push, Google service is still required. --- android/app/build.gradle | 1 + android/app/google-services.json | 55 +++++++++++++++ android/app/src/main/AndroidManifest.xml | 1 + android/build.gradle | 1 + app.config.ts | 5 +- package.json | 1 + src/screens/Tabs/Me/Push.tsx | 51 +++++++------- src/utils/push/constants.ts | 19 +++-- yarn.lock | 89 +++++++++++++++++++++++- 9 files changed, 188 insertions(+), 35 deletions(-) create mode 100644 android/app/google-services.json diff --git a/android/app/build.gradle b/android/app/build.gradle index 947ce178..6411e770 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -1,4 +1,5 @@ apply plugin: "com.android.application" +apply plugin: 'com.google.gms.google-services' import com.android.build.OutputFile import org.apache.tools.ant.taskdefs.condition.Os diff --git a/android/app/google-services.json b/android/app/google-services.json new file mode 100644 index 00000000..9d9e3d20 --- /dev/null +++ b/android/app/google-services.json @@ -0,0 +1,55 @@ +{ + "project_info": { + "project_number": "661638997772", + "project_id": "xmflsct-mastodon-app", + "storage_bucket": "xmflsct-mastodon-app.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:661638997772:android:4fd02851f757f8fa9f8b29", + "android_client_info": { + "package_name": "com.xmflsct.app.tooot" + } + }, + "oauth_client": [ + { + "client_id": "661638997772-erabggnp958v10r0tvsrh3pg880qnvqn.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "com.xmflsct.app.tooot", + "certificate_hash": "53162f104230ee8b7b1372e4f378e2b9607ca16f" + } + }, + { + "client_id": "661638997772-6aiqk97aema0rt280i7nfar3ha2mlgno.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyDUw4s-mhQsHvs4hdIsldsi68ZIygM5MC4" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "661638997772-6aiqk97aema0rt280i7nfar3ha2mlgno.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "661638997772-65g8ce369ugck3ii4ulk6jhb3ijg51kl.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "com.xmflsct.app.tooot", + "app_store_id": "1549772269" + } + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 545f156f..3b22e22f 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -10,6 +10,7 @@ + diff --git a/android/build.gradle b/android/build.gradle index 23aa8859..65e07931 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -25,6 +25,7 @@ buildscript { classpath('com.android.tools.build:gradle:7.2.2') classpath("com.facebook.react:react-native-gradle-plugin") classpath("de.undercouch:gradle-download-task:5.0.1") + classpath 'com.google.gms:google-services:4.3.14' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/app.config.ts b/app.config.ts index 0afae03f..087f6bc6 100644 --- a/app.config.ts +++ b/app.config.ts @@ -15,8 +15,9 @@ export default (): ExpoConfig => ({ }, android: { package: 'com.xmflsct.app.tooot', - permissions: ['CAMERA', 'VIBRATE'], - blockedPermissions: ['USE_BIOMETRIC', 'USE_FINGERPRINT'] + permissions: ['NOTIFICATIONS', 'CAMERA', 'VIBRATE'], + blockedPermissions: ['USE_BIOMETRIC', 'USE_FINGERPRINT'], + googleServicesFile: './android/app/google-services.json' }, plugins: [ [ diff --git a/package.json b/package.json index 144490ed..077a8776 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "@react-native-community/blur": "^4.3.0", "@react-native-community/netinfo": "9.3.7", "@react-native-community/segmented-control": "^2.2.2", + "@react-native-firebase/app": "^16.5.0", "@react-native-menu/menu": "^0.7.3", "@react-navigation/bottom-tabs": "^6.5.2", "@react-navigation/native": "^6.1.1", diff --git a/src/screens/Tabs/Me/Push.tsx b/src/screens/Tabs/Me/Push.tsx index be76f88d..a62f1c06 100644 --- a/src/screens/Tabs/Me/Push.tsx +++ b/src/screens/Tabs/Me/Push.tsx @@ -33,36 +33,39 @@ const TabMePush: React.FC = () => { const [accountDomain] = useAccountStorage.string('auth.account.domain') const [accountId] = useAccountStorage.string('auth.account.id') - const appsQuery = useAppsQuery() + const appsQuery = useAppsQuery({ + options: { + onSuccess: async data => { + if (data.vapid_key) { + await checkPush() + if (isDevelopment) { + setPushAvailable(true) + } else { + setPushAvailable(!!expoToken?.length) + } + } + } + } + }) + + const checkPush = async () => { + const permissions = await Notifications.getPermissionsAsync() + setPushEnabled(permissions.granted) + setPushCanAskAgain(permissions.canAskAgain) + layoutAnimation() + await updateExpoToken() + } const [pushAvailable, setPushAvailable] = useState() const [pushEnabled, setPushEnabled] = useState() const [pushCanAskAgain, setPushCanAskAgain] = useState() useEffect(() => { - const checkPush = async () => { - const permissions = await Notifications.getPermissionsAsync() - setPushEnabled(permissions.granted) - setPushCanAskAgain(permissions.canAskAgain) - layoutAnimation() - await updateExpoToken() - } - - if (appsQuery.data?.vapid_key) { - checkPush() - - if (isDevelopment) { - setPushAvailable(true) - } else { - setPushAvailable(!!expoToken?.length) - } - } - const subscription = AppState.addEventListener('change', checkPush) return () => { subscription.remove() } - }, [appsQuery.data?.vapid_key]) + }, []) const alerts = () => push?.alerts @@ -222,11 +225,11 @@ const TabMePush: React.FC = () => { } }) + setAccountStorage([{ key: 'push', value: { ...push, global: true } }]) + if (Platform.OS === 'android') { setChannels(true) } - - setAccountStorage([{ key: 'push', value: { ...push, global: true } }]) } }} /> @@ -244,11 +247,11 @@ const TabMePush: React.FC = () => { body: { auth: push?.decode ? null : push.key } }) + setAccountStorage([{ key: 'push', value: { ...push, decode: !push.decode } }]) + if (Platform.OS === 'android') { setChannels(true) } - - setAccountStorage([{ key: 'push', value: { ...push, decode: !push.decode } }]) }} /> export const setChannels = async (reset: boolean | undefined = false, specificAccount?: string) => { const account = specificAccount || getGlobalStorage.string('account.active') - const accountDetails = getAccountDetails(['version', 'push']) + const accountDetails = getAccountDetails([ + 'version', + 'push', + 'auth.account.acct', + 'auth.account.domain' + ]) if (!account || !accountDetails) return null + const readableAccount = `@${accountDetails['auth.account.acct']}@${accountDetails['auth.account.domain']}` + const deleteChannel = async (type: string) => - Notifications.deleteNotificationChannelAsync(`${account}_${type}`) + Notifications.deleteNotificationChannelAsync(`${readableAccount}_${type}`) const setChannel = async (type: string) => - Notifications.setNotificationChannelAsync(`${account}_${type}`, { - groupId: account, + Notifications.setNotificationChannelAsync(`${readableAccount}_${type}`, { + groupId: readableAccount, name: i18n.t(`screenTabs:me.push.${type}.heading` as any), importance: Notifications.AndroidImportance.DEFAULT, bypassDnd: false, @@ -62,12 +69,12 @@ export const setChannels = async (reset: boolean | undefined = false, specificAc enableVibrate: true }) - const channelGroup = await Notifications.getNotificationChannelGroupAsync(account) + const channelGroup = await Notifications.getNotificationChannelGroupAsync(readableAccount) if (channelGroup && !reset) { return } if (!channelGroup) { - await Notifications.setNotificationChannelGroupAsync(account, { name: account }) + await Notifications.setNotificationChannelGroupAsync(readableAccount, { name: readableAccount }) } if (!accountDetails.push.decode) { diff --git a/yarn.lock b/yarn.lock index b43642b9..9e39eadf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1656,7 +1656,7 @@ __metadata: languageName: node linkType: hard -"@expo/config-plugins@npm:5.0.4, @expo/config-plugins@npm:~5.0.3": +"@expo/config-plugins@npm:5.0.4, @expo/config-plugins@npm:^5.0.4, @expo/config-plugins@npm:~5.0.3": version: 5.0.4 resolution: "@expo/config-plugins@npm:5.0.4" dependencies: @@ -2979,6 +2979,20 @@ __metadata: languageName: node linkType: hard +"@react-native-firebase/app@npm:^16.5.0": + version: 16.5.0 + resolution: "@react-native-firebase/app@npm:16.5.0" + dependencies: + "@expo/config-plugins": ^5.0.4 + opencollective-postinstall: ^2.0.1 + superstruct: ^0.6.2 + peerDependencies: + react: "*" + react-native: "*" + checksum: 2eab11544f8b4e932127119b6485e43788214df8264f1f84b06695ad1ca0ae88e9969c9e8d8005ab986637223991617960b1556dee43453cc38716d537d9c81a + languageName: node + linkType: hard + "@react-native-menu/menu@npm:^0.7.3": version: 0.7.3 resolution: "@react-native-menu/menu@npm:0.7.3" @@ -4619,6 +4633,18 @@ __metadata: languageName: node linkType: hard +"clone-deep@npm:^2.0.1": + version: 2.0.2 + resolution: "clone-deep@npm:2.0.2" + dependencies: + for-own: ^1.0.0 + is-plain-object: ^2.0.4 + kind-of: ^6.0.0 + shallow-clone: ^1.0.0 + checksum: c33ae31e332cdfd477a8115c9d044984eb69bf009fce3e1f0ff002176652f572d8742aa5e6caeaf16cf5d6084e33fe51bfa482fec53f43e767b3518c797955b1 + languageName: node + linkType: hard + "clone-deep@npm:^4.0.1": version: 4.0.1 resolution: "clone-deep@npm:4.0.1" @@ -6109,13 +6135,29 @@ __metadata: languageName: node linkType: hard -"for-in@npm:^1.0.2": +"for-in@npm:^0.1.3": + version: 0.1.8 + resolution: "for-in@npm:0.1.8" + checksum: f5bdad7811700ee6a0f96b33d72a1db966aea75a1f03c7245d147f8369305e709f53a55ee7ae8eaddcfa85c7c89bca78472be8f1bc605475ce5bb2c70f77f8da + languageName: node + linkType: hard + +"for-in@npm:^1.0.1, for-in@npm:^1.0.2": version: 1.0.2 resolution: "for-in@npm:1.0.2" checksum: 09f4ae93ce785d253ac963d94c7f3432d89398bf25ac7a24ed034ca393bf74380bdeccc40e0f2d721a895e54211b07c8fad7132e8157827f6f7f059b70b4043d languageName: node linkType: hard +"for-own@npm:^1.0.0": + version: 1.0.0 + resolution: "for-own@npm:1.0.0" + dependencies: + for-in: ^1.0.1 + checksum: 233238f6e9060f61295a7f7c7e3e9de11aaef57e82a108e7f350dc92ae84fe2189848077ac4b8db47fd8edd45337ed8d9f66bd0b1efa4a6a1b3f38aa21b7ab2e + languageName: node + linkType: hard + "form-data@npm:^3.0.1": version: 3.0.1 resolution: "form-data@npm:3.0.1" @@ -7557,7 +7599,7 @@ __metadata: languageName: node linkType: hard -"kind-of@npm:^6.0.0, kind-of@npm:^6.0.2": +"kind-of@npm:^6.0.0, kind-of@npm:^6.0.1, kind-of@npm:^6.0.2": version: 6.0.3 resolution: "kind-of@npm:6.0.3" checksum: 3ab01e7b1d440b22fe4c31f23d8d38b4d9b91d9f291df683476576493d5dfd2e03848a8b05813dd0c3f0e835bc63f433007ddeceb71f05cb25c45ae1b19c6d3b @@ -8418,6 +8460,16 @@ __metadata: languageName: node linkType: hard +"mixin-object@npm:^2.0.1": + version: 2.0.1 + resolution: "mixin-object@npm:2.0.1" + dependencies: + for-in: ^0.1.3 + is-extendable: ^0.1.1 + checksum: 7d0eb7c2f06435fcc01d132824b4c973a0df689a117d8199d79911b506363b6f4f86a84458a63f3acfa7388f3052612cfe27105400b4932678452925a9739a4c + languageName: node + linkType: hard + "mkdirp@npm:^0.5.1, mkdirp@npm:^0.5.5, mkdirp@npm:~0.5.1": version: 0.5.6 resolution: "mkdirp@npm:0.5.6" @@ -8867,6 +8919,15 @@ __metadata: languageName: node linkType: hard +"opencollective-postinstall@npm:^2.0.1": + version: 2.0.3 + resolution: "opencollective-postinstall@npm:2.0.3" + bin: + opencollective-postinstall: index.js + checksum: 0a68c5cef135e46d11e665d5077398285d1ce5311c948e8327b435791c409744d4a6bb9c55bd6507fb5f2ef34b0ad920565adcdaf974cbdae701aead6f32b396 + languageName: node + linkType: hard + "opn@npm:^5.4.0": version: 5.5.0 resolution: "opn@npm:5.5.0" @@ -10496,6 +10557,17 @@ __metadata: languageName: node linkType: hard +"shallow-clone@npm:^1.0.0": + version: 1.0.0 + resolution: "shallow-clone@npm:1.0.0" + dependencies: + is-extendable: ^0.1.1 + kind-of: ^5.0.0 + mixin-object: ^2.0.1 + checksum: d4fd93b82d9fdd135027510f4beb04479de96c50b5392a17b022cf0942d17d43bff92aa83dfc30ddf962c0ed015e7c686c2ce677b85760ca5a8db9ebd5f1d791 + languageName: node + linkType: hard + "shallow-clone@npm:^3.0.0": version: 3.0.1 resolution: "shallow-clone@npm:3.0.1" @@ -11001,6 +11073,16 @@ __metadata: languageName: node linkType: hard +"superstruct@npm:^0.6.2": + version: 0.6.2 + resolution: "superstruct@npm:0.6.2" + dependencies: + clone-deep: ^2.0.1 + kind-of: ^6.0.1 + checksum: f95e4049becb928baa531fe56256a74b050a2e4da0bee09ccd0031e08fffd521defeb1d37881b93e6861fa1a7c17c48f3834a99af83cb3ad60c9e6079e840a65 + languageName: node + linkType: hard + "supports-color@npm:^5.3.0": version: 5.5.0 resolution: "supports-color@npm:5.5.0" @@ -11268,6 +11350,7 @@ __metadata: "@react-native-community/blur": ^4.3.0 "@react-native-community/netinfo": 9.3.7 "@react-native-community/segmented-control": ^2.2.2 + "@react-native-firebase/app": ^16.5.0 "@react-native-menu/menu": ^0.7.3 "@react-navigation/bottom-tabs": ^6.5.2 "@react-navigation/native": ^6.1.1