diff --git a/frontend/occupi-mobile4/.gitignore b/frontend/occupi-mobile4/.gitignore
index d3e535a6..b68c06ef 100644
--- a/frontend/occupi-mobile4/.gitignore
+++ b/frontend/occupi-mobile4/.gitignore
@@ -12,6 +12,8 @@ web-build/
eas.json
app.json
+occupi-4d02a-firebase-adminsdk-4ea8s-545f5460aa.json
+google-services.json
# macOS
.DS_Store
diff --git a/frontend/occupi-mobile4/.gradle/8.1.1/checksums/checksums.lock b/frontend/occupi-mobile4/.gradle/8.1.1/checksums/checksums.lock
new file mode 100644
index 00000000..ba1fe258
Binary files /dev/null and b/frontend/occupi-mobile4/.gradle/8.1.1/checksums/checksums.lock differ
diff --git a/frontend/occupi-mobile4/.gradle/8.1.1/dependencies-accessors/dependencies-accessors.lock b/frontend/occupi-mobile4/.gradle/8.1.1/dependencies-accessors/dependencies-accessors.lock
new file mode 100644
index 00000000..97885e53
Binary files /dev/null and b/frontend/occupi-mobile4/.gradle/8.1.1/dependencies-accessors/dependencies-accessors.lock differ
diff --git a/frontend/occupi-mobile4/.gradle/8.1.1/dependencies-accessors/gc.properties b/frontend/occupi-mobile4/.gradle/8.1.1/dependencies-accessors/gc.properties
new file mode 100644
index 00000000..e69de29b
diff --git a/frontend/occupi-mobile4/.gradle/8.1.1/fileChanges/last-build.bin b/frontend/occupi-mobile4/.gradle/8.1.1/fileChanges/last-build.bin
new file mode 100644
index 00000000..f76dd238
Binary files /dev/null and b/frontend/occupi-mobile4/.gradle/8.1.1/fileChanges/last-build.bin differ
diff --git a/frontend/occupi-mobile4/.gradle/8.1.1/fileHashes/fileHashes.lock b/frontend/occupi-mobile4/.gradle/8.1.1/fileHashes/fileHashes.lock
new file mode 100644
index 00000000..0f0c5dd2
Binary files /dev/null and b/frontend/occupi-mobile4/.gradle/8.1.1/fileHashes/fileHashes.lock differ
diff --git a/frontend/occupi-mobile4/.gradle/8.1.1/gc.properties b/frontend/occupi-mobile4/.gradle/8.1.1/gc.properties
new file mode 100644
index 00000000..e69de29b
diff --git a/frontend/occupi-mobile4/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/frontend/occupi-mobile4/.gradle/buildOutputCleanup/buildOutputCleanup.lock
new file mode 100644
index 00000000..efd5aa3b
Binary files /dev/null and b/frontend/occupi-mobile4/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ
diff --git a/frontend/occupi-mobile4/.gradle/buildOutputCleanup/cache.properties b/frontend/occupi-mobile4/.gradle/buildOutputCleanup/cache.properties
new file mode 100644
index 00000000..c0066b57
--- /dev/null
+++ b/frontend/occupi-mobile4/.gradle/buildOutputCleanup/cache.properties
@@ -0,0 +1,2 @@
+#Thu Jul 04 00:58:00 SAST 2024
+gradle.version=8.1.1
diff --git a/frontend/occupi-mobile4/.gradle/buildOutputCleanup/outputFiles.bin b/frontend/occupi-mobile4/.gradle/buildOutputCleanup/outputFiles.bin
new file mode 100644
index 00000000..0de379d8
Binary files /dev/null and b/frontend/occupi-mobile4/.gradle/buildOutputCleanup/outputFiles.bin differ
diff --git a/frontend/occupi-mobile4/.gradle/vcs-1/gc.properties b/frontend/occupi-mobile4/.gradle/vcs-1/gc.properties
new file mode 100644
index 00000000..e69de29b
diff --git a/frontend/occupi-mobile4/app.json b/frontend/occupi-mobile4/app.json
index 2b11cd34..07090b7c 100644
--- a/frontend/occupi-mobile4/app.json
+++ b/frontend/occupi-mobile4/app.json
@@ -27,7 +27,8 @@
"foregroundImage": "./assets/images/adaptive-icon.png",
"backgroundColor": "#ffffff"
},
- "package": "com.y2kodedev.occupi"
+ "package": "com.y2kodedev.occupi",
+ "googleServicesFile": "./google-services.json"
},
"web": {
"bundler": "metro",
diff --git a/frontend/occupi-mobile4/app/_layout.tsx b/frontend/occupi-mobile4/app/_layout.tsx
index 052c3e5c..a5bb7d3f 100644
--- a/frontend/occupi-mobile4/app/_layout.tsx
+++ b/frontend/occupi-mobile4/app/_layout.tsx
@@ -52,6 +52,7 @@ export default function RootLayout() {
+
);
diff --git a/frontend/occupi-mobile4/app/build.gradle.kts b/frontend/occupi-mobile4/app/build.gradle.kts
new file mode 100644
index 00000000..9711936a
--- /dev/null
+++ b/frontend/occupi-mobile4/app/build.gradle.kts
@@ -0,0 +1,22 @@
+plugins {
+ id("com.android.application")
+
+ // Add the Google services Gradle plugin
+ id("com.google.gms.google-services")
+
+ ...
+}
+
+dependencies {
+ // Import the Firebase BoM
+ implementation(platform("com.google.firebase:firebase-bom:33.1.1"))
+
+
+ // TODO: Add the dependencies for Firebase products you want to use
+ // When using the BoM, don't specify versions in Firebase dependencies
+ implementation("com.google.firebase:firebase-analytics")
+
+
+ // Add the dependencies for any other desired Firebase products
+ // https://firebase.google.com/docs/android/setup#available-libraries
+}
\ No newline at end of file
diff --git a/frontend/occupi-mobile4/app/notiftester.tsx b/frontend/occupi-mobile4/app/notiftester.tsx
new file mode 100644
index 00000000..a4309ff1
--- /dev/null
+++ b/frontend/occupi-mobile4/app/notiftester.tsx
@@ -0,0 +1,7 @@
+import NotifTester from "../screens/Settings/NotifTester";
+
+export default function Home() {
+ return (
+
+ );
+}
diff --git a/frontend/occupi-mobile4/build.gradle.kts b/frontend/occupi-mobile4/build.gradle.kts
new file mode 100644
index 00000000..a1f19aa9
--- /dev/null
+++ b/frontend/occupi-mobile4/build.gradle.kts
@@ -0,0 +1,7 @@
+plugins {
+ // ...
+
+ // Add the dependency for the Google services Gradle plugin
+ id("com.google.gms.google-services") version "4.4.2" apply false
+
+}
\ No newline at end of file
diff --git a/frontend/occupi-mobile4/package-lock.json b/frontend/occupi-mobile4/package-lock.json
index 5d9cd007..393ddead 100644
--- a/frontend/occupi-mobile4/package-lock.json
+++ b/frontend/occupi-mobile4/package-lock.json
@@ -25,6 +25,7 @@
"expo": "~51.0.14",
"expo-blur": "^13.0.2",
"expo-constants": "~16.0.2",
+ "expo-device": "~6.0.2",
"expo-file-system": "^17.0.1",
"expo-font": "~12.0.7",
"expo-linear-gradient": "^13.0.2",
@@ -12393,6 +12394,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",
diff --git a/frontend/occupi-mobile4/package.json b/frontend/occupi-mobile4/package.json
index 4e416484..376f072e 100644
--- a/frontend/occupi-mobile4/package.json
+++ b/frontend/occupi-mobile4/package.json
@@ -69,7 +69,8 @@
"react-native-svg": "^15.3.0",
"react-native-web": "~0.19.10",
"zod": "^3.23.8",
- "expo-notifications": "~0.28.9"
+ "expo-notifications": "~0.28.9",
+ "expo-device": "~6.0.2"
},
"devDependencies": {
"@babel/core": "^7.20.0",
diff --git a/frontend/occupi-mobile4/screens/Login/SplashScreen.tsx b/frontend/occupi-mobile4/screens/Login/SplashScreen.tsx
index 3e0c538a..701545a4 100644
--- a/frontend/occupi-mobile4/screens/Login/SplashScreen.tsx
+++ b/frontend/occupi-mobile4/screens/Login/SplashScreen.tsx
@@ -93,7 +93,7 @@ export default function SplashScreen() {
useEffect(() => {
const timer = setTimeout(() => {
setSelectedIndex(1); // Assuming Onboarding1 is at index 1
- router.replace('/settings'); // Navigate to Onboarding1 screen
+ router.replace('/notiftester'); // Navigate to Onboarding1 screen
}, 5000); // 8 seconds
return () => clearTimeout(timer); // Clean up timer on component unmount
diff --git a/frontend/occupi-mobile4/screens/Settings/NotifTester.tsx b/frontend/occupi-mobile4/screens/Settings/NotifTester.tsx
new file mode 100644
index 00000000..ed623297
--- /dev/null
+++ b/frontend/occupi-mobile4/screens/Settings/NotifTester.tsx
@@ -0,0 +1,131 @@
+import { useState, useEffect, useRef } from 'react';
+import { Text, View, Button, Platform } from 'react-native';
+import * as Device from 'expo-device';
+import * as Notifications from 'expo-notifications';
+import Constants from 'expo-constants';
+
+
+Notifications.setNotificationHandler({
+ handleNotification: async () => ({
+ shouldShowAlert: true,
+ shouldPlaySound: false,
+ shouldSetBadge: false,
+ }),
+});
+
+
+
+async function sendPushNotification(expoPushToken: string) {
+ const message = {
+ to: expoPushToken,
+ sound: 'default',
+ title: 'Original Title',
+ body: 'And here is the body!',
+ data: { someData: 'goes here' },
+ };
+
+ await fetch('https://exp.host/--/api/v2/push/send', {
+ method: 'POST',
+ headers: {
+ Accept: 'application/json',
+ 'Accept-encoding': 'gzip, deflate',
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(message),
+ });
+}
+
+
+function handleRegistrationError(errorMessage: string) {
+ alert(errorMessage);
+ throw new Error(errorMessage);
+}
+
+async function registerForPushNotificationsAsync() {
+ if (Platform.OS === 'android') {
+ Notifications.setNotificationChannelAsync('default', {
+ name: 'default',
+ importance: Notifications.AndroidImportance.MAX,
+ vibrationPattern: [0, 250, 250, 250],
+ lightColor: '#FF231F7C',
+ });
+ }
+
+ 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;
+ console.log(pushTokenString);
+ return pushTokenString;
+ } catch (e: unknown) {
+ handleRegistrationError(`${e}`);
+ }
+ } else {
+ handleRegistrationError('Must use physical device for push notifications');
+ }
+}
+
+export default function NotifTester() {
+ const [expoPushToken, setExpoPushToken] = useState('');
+ const [notification, setNotification] = useState(
+ undefined
+ );
+ const notificationListener = useRef();
+ const responseListener = useRef();
+
+ useEffect(() => {
+ registerForPushNotificationsAsync()
+ .then(token => setExpoPushToken(token ?? ''))
+ .catch((error: any) => setExpoPushToken(`${error}`));
+
+ notificationListener.current = Notifications.addNotificationReceivedListener(notification => {
+ setNotification(notification);
+ });
+
+ responseListener.current = Notifications.addNotificationResponseReceivedListener(response => {
+ console.log(response);
+ });
+
+ return () => {
+ notificationListener.current &&
+ Notifications.removeNotificationSubscription(notificationListener.current);
+ responseListener.current &&
+ Notifications.removeNotificationSubscription(responseListener.current);
+ };
+ }, []);
+
+ return (
+
+ Your Expo push token: {expoPushToken}
+
+ Title: {notification && notification.request.content.title}
+ Body: {notification && notification.request.content.body}
+ Data: {notification && JSON.stringify(notification.request.content.data)}
+
+
+ );
+}
diff --git a/occupi-backend/go.mod b/occupi-backend/go.mod
index f28d2e45..19fa9d6a 100644
--- a/occupi-backend/go.mod
+++ b/occupi-backend/go.mod
@@ -19,6 +19,8 @@ require (
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
)
+require github.com/oliveroneill/exponent-server-sdk-golang v0.0.0-20210823140141-d050598be512 // indirect
+
require (
github.com/aymerick/douceur v0.2.0 // indirect
github.com/bytedance/sonic v1.11.7 // indirect
diff --git a/occupi-backend/go.sum b/occupi-backend/go.sum
index e6bd69f7..db65ab4a 100644
--- a/occupi-backend/go.sum
+++ b/occupi-backend/go.sum
@@ -89,6 +89,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
+github.com/oliveroneill/exponent-server-sdk-golang v0.0.0-20210823140141-d050598be512 h1:/ZSmjwl1inqsiHMhn+sPlEtSHdVTf+TH3LNGGdMQ/vA=
+github.com/oliveroneill/exponent-server-sdk-golang v0.0.0-20210823140141-d050598be512/go.mod h1:Isv/48UnAjtxS8FD80Bito3ZJqZRyIMxKARIEITfW4k=
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
diff --git a/occupi-backend/notifications/main.go b/occupi-backend/notifications/main.go
new file mode 100644
index 00000000..4fc3030c
--- /dev/null
+++ b/occupi-backend/notifications/main.go
@@ -0,0 +1,39 @@
+package main
+
+import (
+ "fmt"
+ expo "github.com/oliveroneill/exponent-server-sdk-golang/sdk"
+)
+
+func main() {
+ // To check the token is valid
+ pushToken, err := expo.NewExponentPushToken("ExponentPushToken[5cpRYINQu42bhcKM5b7Vsb]")
+ if err != nil {
+ panic(err)
+ }
+
+ // Create a new Expo SDK client
+ client := expo.NewPushClient(nil)
+
+ // Publish message
+ response, err := client.Publish(
+ &expo.PushMessage{
+ To: []expo.ExponentPushToken{pushToken},
+ Body: "This is a test notification",
+ Data: map[string]string{"withSome": "data"},
+ Sound: "default",
+ Title: "Notification Title",
+ Priority: expo.DefaultPriority,
+ },
+ )
+
+ // Check errors
+ if err != nil {
+ panic(err)
+ }
+
+ // Validate responses
+ if response.ValidateResponse() != nil {
+ fmt.Println(response.PushMessage.To, "failed")
+ }
+}
\ No newline at end of file