summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSanto Cariotti <santo@dcariotti.me>2024-09-05 14:18:44 +0200
committerSanto Cariotti <santo@dcariotti.me>2024-09-05 14:18:44 +0200
commitb29af46f9e53983e7a901253921e8fc4eb269bd7 (patch)
treeb294f667900ecb0e0be9b82154fd2811ac975798
parent88e4d0b3f44720b1b1444ad563b53bcfc64187e0 (diff)
Set up notifications
Google services file and Firebase adminsdk file are private
-rw-r--r--app.json1
-rw-r--r--app/(tabs)/index.tsx89
-rw-r--r--package-lock.json249
-rw-r--r--package.json4
4 files changed, 342 insertions, 1 deletions
diff --git a/app.json b/app.json
index f97e85b..96e872e 100644
--- a/app.json
+++ b/app.json
@@ -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",