diff options
author | Santo Cariotti <santo@dcariotti.me> | 2024-09-05 14:18:44 +0200 |
---|---|---|
committer | Santo Cariotti <santo@dcariotti.me> | 2024-09-05 14:18:44 +0200 |
commit | b29af46f9e53983e7a901253921e8fc4eb269bd7 (patch) | |
tree | b294f667900ecb0e0be9b82154fd2811ac975798 | |
parent | 88e4d0b3f44720b1b1444ad563b53bcfc64187e0 (diff) |
Set up notifications
Google services file and Firebase adminsdk file are private
-rw-r--r-- | app.json | 1 | ||||
-rw-r--r-- | app/(tabs)/index.tsx | 89 | ||||
-rw-r--r-- | package-lock.json | 249 | ||||
-rw-r--r-- | package.json | 4 |
4 files changed, 342 insertions, 1 deletions
@@ -20,6 +20,7 @@ "foregroundImage": "./assets/images/adaptive-icon.png", "backgroundColor": "#ffffff" }, + "googleServicesFile": "./google-services.json", "package": "com.unibo.cas4" }, "web": { diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx index 960a502..94e85d6 100644 --- a/app/(tabs)/index.tsx +++ b/app/(tabs)/index.tsx @@ -5,6 +5,63 @@ import { ThemedView } from '@/components/ThemedView'; import React, { useState, useEffect, useRef } from 'react'; import AsyncStorage from '@react-native-async-storage/async-storage'; import MapView, { Marker } from 'react-native-maps'; +import * as Notifications from 'expo-notifications'; +import * as Device from 'expo-device'; +import Constants from 'expo-constants'; + +Notifications.setNotificationHandler({ + handleNotification: async () => ({ + shouldShowAlert: true, + shouldPlaySound: true, + shouldSetBadge: false, + }), +}); + + +function handleRegistrationError(errorMessage: string) { + Alert.alert("Error registering this device", errorMessage); +} + +async function registerForPushNotificationsAsync() { + if (Platform.OS === 'android') { + Notifications.setNotificationChannelAsync('default', { + name: 'default', + importance: Notifications.AndroidImportance.MAX, + vibrationPattern: [0, 250, 250, 250], + lightColor: '#007AFF', + }); + } + + if (Device.isDevice) { + const { status: existingStatus } = await Notifications.getPermissionsAsync(); + let finalStatus = existingStatus; + if (existingStatus !== 'granted') { + const { status } = await Notifications.requestPermissionsAsync(); + finalStatus = status; + } + if (finalStatus !== 'granted') { + handleRegistrationError('Permission not granted to get push token for push notification!'); + return; + } + const projectId = + Constants?.expoConfig?.extra?.eas?.projectId ?? Constants?.easConfig?.projectId; + if (!projectId) { + handleRegistrationError('Project ID not found'); + } + try { + const pushTokenString = ( + await Notifications.getExpoPushTokenAsync({ + projectId, + }) + ).data; + return pushTokenString; + } catch (e: unknown) { + handleRegistrationError(`${e}`); + } + } else { + handleRegistrationError('Must use physical device for push notifications'); + } +} export default function HomeScreen() { const [email, setEmail] = useState(''); @@ -72,6 +129,38 @@ export default function HomeScreen() { await storeUserId(String(userId)); setToken(accessToken); setUserId(String(userId)); + + registerForPushNotificationsAsync() + .then(async notificationToken => { + if (!notificationToken) return; + + const regex = /ExponentPushToken\[(.*?)\]/; + const match = notificationToken.match(regex); + + if (match && match[1]) { + notificationToken = match[1]; + } + await fetch(`${process.env.EXPO_PUBLIC_API_URL}/graphql`, { + method: 'POST', + headers: { + 'Authorization': `Bearer ${accessToken}`, + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + query: ` + mutation RegisterDevice($input: RegisterNotificationToken!) { + registerDevice(input: $input) { id name email } + } + `, + variables: { + input: { + token: notificationToken, + }, + }, + }), + }) + }) + .catch((error: any) => alert(`${error}`)); } } catch (err) { console.error('Login Error:', err); diff --git a/package-lock.json b/package-lock.json index 068452a..9b34af1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,8 +13,10 @@ "@react-navigation/native": "^6.0.2", "expo": "~51.0.28", "expo-constants": "~16.0.2", + "expo-device": "~6.0.2", "expo-font": "~12.0.9", "expo-linking": "~6.3.1", + "expo-notifications": "~0.28.16", "expo-router": "~3.5.23", "expo-splash-screen": "~0.27.5", "expo-status-bar": "~1.12.1", @@ -3334,6 +3336,11 @@ "@hapi/hoek": "^9.0.0" } }, + "node_modules/@ide/backoff": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@ide/backoff/-/backoff-1.0.0.tgz", + "integrity": "sha512-F0YfUDjvT+Mtt/R4xdl2X0EYCHMMiJqNLdxHD++jDT5ydEFIyqbCHh51Qx2E211dgZprPKhV7sHmnXKpLuvc5g==" + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -7126,6 +7133,18 @@ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" }, + "node_modules/assert": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", + "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", + "dependencies": { + "call-bind": "^1.0.2", + "is-nan": "^1.3.2", + "object-is": "^1.1.5", + "object.assign": "^4.1.4", + "util": "^0.12.5" + } + }, "node_modules/ast-types": { "version": "0.15.2", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.15.2.tgz", @@ -7581,6 +7600,11 @@ "@babel/core": "^7.0.0" } }, + "node_modules/badgin": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/badgin/-/badgin-1.2.3.tgz", + "integrity": "sha512-NQGA7LcfCpSzIbGRbkgjgdWkjy7HI+Th5VLxTJfW5EeaAf3fnS+xWQaQOCYiny+q6QSvxqoSO04vCx+4u++EJw==" + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -9306,6 +9330,14 @@ "expo": "bin/cli" } }, + "node_modules/expo-application": { + "version": "5.9.1", + "resolved": "https://registry.npmjs.org/expo-application/-/expo-application-5.9.1.tgz", + "integrity": "sha512-uAfLBNZNahnDZLRU41ZFmNSKtetHUT9Ua557/q189ua0AWV7pQjoVAx49E4953feuvqc9swtU3ScZ/hN1XO/FQ==", + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo-asset": { "version": "10.0.10", "resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-10.0.10.tgz", @@ -9331,6 +9363,39 @@ "expo": "*" } }, + "node_modules/expo-device": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/expo-device/-/expo-device-6.0.2.tgz", + "integrity": "sha512-sCt91CuTmAuMXX4SlFOn4lIos2UIr8vb0jDstDDZXys6kErcj0uynC7bQAMreU5uRUTKMAl4MAMpKt9ufCXPBw==", + "dependencies": { + "ua-parser-js": "^0.7.33" + }, + "peerDependencies": { + "expo": "*" + } + }, + "node_modules/expo-device/node_modules/ua-parser-js": { + "version": "0.7.38", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.38.tgz", + "integrity": "sha512-fYmIy7fKTSFAhG3fuPlubeGaMoAd6r0rSnfEsO5nEY55i26KSLt9EH7PLQiiqPUhNqYIJvSkTy1oArIcXAbPbA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "engines": { + "node": "*" + } + }, "node_modules/expo-file-system": { "version": "17.0.1", "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-17.0.1.tgz", @@ -9489,6 +9554,57 @@ "invariant": "^2.2.4" } }, + "node_modules/expo-notifications": { + "version": "0.28.16", + "resolved": "https://registry.npmjs.org/expo-notifications/-/expo-notifications-0.28.16.tgz", + "integrity": "sha512-sj4oDip+uFNmxieGHkfS2Usrwbw2jfOTfQ22a7z5tdSo/vD6jWMlCHOnJifqYLjPxyqf9SLTsQWO3bmk7MY2Yg==", + "dependencies": { + "@expo/image-utils": "^0.5.0", + "@ide/backoff": "^1.0.0", + "abort-controller": "^3.0.0", + "assert": "^2.0.0", + "badgin": "^1.1.5", + "expo-application": "~5.9.0", + "expo-constants": "~16.0.0", + "fs-extra": "^9.1.0" + }, + "peerDependencies": { + "expo": "*" + } + }, + "node_modules/expo-notifications/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/expo-notifications/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/expo-notifications/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/expo-router": { "version": "3.5.23", "resolved": "https://registry.npmjs.org/expo-router/-/expo-router-3.5.23.tgz", @@ -10895,6 +11011,21 @@ "node": ">=0.10.0" } }, + "node_modules/is-nan": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-negative-zero": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", @@ -14855,6 +14986,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", @@ -20666,6 +20812,11 @@ "@hapi/hoek": "^9.0.0" } }, + "@ide/backoff": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@ide/backoff/-/backoff-1.0.0.tgz", + "integrity": "sha512-F0YfUDjvT+Mtt/R4xdl2X0EYCHMMiJqNLdxHD++jDT5ydEFIyqbCHh51Qx2E211dgZprPKhV7sHmnXKpLuvc5g==" + }, "@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -23480,6 +23631,18 @@ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" }, + "assert": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", + "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", + "requires": { + "call-bind": "^1.0.2", + "is-nan": "^1.3.2", + "object-is": "^1.1.5", + "object.assign": "^4.1.4", + "util": "^0.12.5" + } + }, "ast-types": { "version": "0.15.2", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.15.2.tgz", @@ -23839,6 +24002,11 @@ "babel-preset-current-node-syntax": "^1.0.0" } }, + "badgin": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/badgin/-/badgin-1.2.3.tgz", + "integrity": "sha512-NQGA7LcfCpSzIbGRbkgjgdWkjy7HI+Th5VLxTJfW5EeaAf3fnS+xWQaQOCYiny+q6QSvxqoSO04vCx+4u++EJw==" + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -25097,6 +25265,12 @@ "whatwg-url-without-unicode": "8.0.0-3" } }, + "expo-application": { + "version": "5.9.1", + "resolved": "https://registry.npmjs.org/expo-application/-/expo-application-5.9.1.tgz", + "integrity": "sha512-uAfLBNZNahnDZLRU41ZFmNSKtetHUT9Ua557/q189ua0AWV7pQjoVAx49E4953feuvqc9swtU3ScZ/hN1XO/FQ==", + "requires": {} + }, "expo-asset": { "version": "10.0.10", "resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-10.0.10.tgz", @@ -25116,6 +25290,21 @@ "@expo/env": "~0.3.0" } }, + "expo-device": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/expo-device/-/expo-device-6.0.2.tgz", + "integrity": "sha512-sCt91CuTmAuMXX4SlFOn4lIos2UIr8vb0jDstDDZXys6kErcj0uynC7bQAMreU5uRUTKMAl4MAMpKt9ufCXPBw==", + "requires": { + "ua-parser-js": "^0.7.33" + }, + "dependencies": { + "ua-parser-js": { + "version": "0.7.38", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.38.tgz", + "integrity": "sha512-fYmIy7fKTSFAhG3fuPlubeGaMoAd6r0rSnfEsO5nEY55i26KSLt9EH7PLQiiqPUhNqYIJvSkTy1oArIcXAbPbA==" + } + } + }, "expo-file-system": { "version": "17.0.1", "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-17.0.1.tgz", @@ -25237,6 +25426,48 @@ "invariant": "^2.2.4" } }, + "expo-notifications": { + "version": "0.28.16", + "resolved": "https://registry.npmjs.org/expo-notifications/-/expo-notifications-0.28.16.tgz", + "integrity": "sha512-sj4oDip+uFNmxieGHkfS2Usrwbw2jfOTfQ22a7z5tdSo/vD6jWMlCHOnJifqYLjPxyqf9SLTsQWO3bmk7MY2Yg==", + "requires": { + "@expo/image-utils": "^0.5.0", + "@ide/backoff": "^1.0.0", + "abort-controller": "^3.0.0", + "assert": "^2.0.0", + "badgin": "^1.1.5", + "expo-application": "~5.9.0", + "expo-constants": "~16.0.0", + "fs-extra": "^9.1.0" + }, + "dependencies": { + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==" + } + } + }, "expo-router": { "version": "3.5.23", "resolved": "https://registry.npmjs.org/expo-router/-/expo-router-3.5.23.tgz", @@ -26232,6 +26463,15 @@ } } }, + "is-nan": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, "is-negative-zero": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", @@ -29117,6 +29357,15 @@ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==" }, + "object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + } + }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", diff --git a/package.json b/package.json index ad0ba5a..92f58d3 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,9 @@ "react-native-safe-area-context": "4.10.5", "react-native-screens": "3.31.1", "react-native-web": "~0.19.10", - "typescript-language-server": "^4.3.3" + "typescript-language-server": "^4.3.3", + "expo-notifications": "~0.28.16", + "expo-device": "~6.0.2" }, "devDependencies": { "@babel/core": "^7.20.0", |