upd: push notifikasi
Deskripsi: - blm selesai NO Issues
This commit is contained in:
43
.easignore
Normal file
43
.easignore
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# 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
|
||||||
|
|
||||||
|
app-example
|
||||||
|
|
||||||
|
x.ts
|
||||||
|
x.sh
|
||||||
|
/android
|
||||||
|
/ios
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -39,3 +39,6 @@ app-example
|
|||||||
|
|
||||||
x.ts
|
x.ts
|
||||||
x.sh
|
x.sh
|
||||||
|
|
||||||
|
google-services.json
|
||||||
|
mobile-darmasaba-firebase-adminsdk-fbsvc-f5abb292b5.json
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
apply plugin: "com.android.application"
|
apply plugin: "com.android.application"
|
||||||
apply plugin: "org.jetbrains.kotlin.android"
|
apply plugin: "org.jetbrains.kotlin.android"
|
||||||
apply plugin: "com.facebook.react"
|
apply plugin: "com.facebook.react"
|
||||||
|
apply from: new File(["node", "--print", "require.resolve('expo-modules-core/package.json')"].execute(null, rootDir).text.trim(), "../gradle.groovy")
|
||||||
|
apply from: new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), "../react.gradle")
|
||||||
|
apply from: new File(["node", "--print", "require.resolve('expo-updates/package.json')"].execute(null, rootDir).text.trim(), "../scripts/create-manifest-android.gradle")
|
||||||
|
|
||||||
def projectRoot = rootDir.getAbsoluteFile().getParentFile().getAbsolutePath()
|
def projectRoot = rootDir.getAbsoluteFile().getParentFile().getAbsolutePath()
|
||||||
|
|
||||||
|
|||||||
@@ -36,3 +36,9 @@ useExpoModules()
|
|||||||
|
|
||||||
include ':app'
|
include ':app'
|
||||||
includeBuild(new File(["node", "--print", "require.resolve('@react-native/gradle-plugin/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim()).getParentFile())
|
includeBuild(new File(["node", "--print", "require.resolve('@react-native/gradle-plugin/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim()).getParentFile())
|
||||||
|
|
||||||
|
apply from: new File(["node", "--print", "require.resolve('expo-modules-core/package.json')"].execute(null, rootDir).text.trim(), "../gradle.groovy");
|
||||||
|
includeUnimodulesProjects()
|
||||||
|
|
||||||
|
apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json')"].execute(null, rootDir).text.trim(), "../native_modules.gradle");
|
||||||
|
applyNativeModulesSettingsGradle(settings)
|
||||||
|
|||||||
8
app.json
8
app.json
@@ -10,14 +10,18 @@
|
|||||||
"newArchEnabled": true,
|
"newArchEnabled": true,
|
||||||
"ios": {
|
"ios": {
|
||||||
"supportsTablet": true,
|
"supportsTablet": true,
|
||||||
"bundleIdentifier": "mobiledarmasaba.app"
|
"bundleIdentifier": "mobiledarmasaba.app",
|
||||||
|
"infoPlist": {
|
||||||
|
"ITSAppUsesNonExemptEncryption": false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"android": {
|
"android": {
|
||||||
"package": "mobiledarmasaba.app",
|
"package": "mobiledarmasaba.app",
|
||||||
"adaptiveIcon": {
|
"adaptiveIcon": {
|
||||||
"foregroundImage": "./assets/images/adaptive-icon.png",
|
"foregroundImage": "./assets/images/adaptive-icon.png",
|
||||||
"backgroundColor": "#ffffff"
|
"backgroundColor": "#ffffff"
|
||||||
}
|
},
|
||||||
|
"googleServicesFile": "./google-services.json"
|
||||||
},
|
},
|
||||||
"web": {
|
"web": {
|
||||||
"bundler": "metro",
|
"bundler": "metro",
|
||||||
|
|||||||
43
lib/registerForPushNotificationsAsync.ts
Normal file
43
lib/registerForPushNotificationsAsync.ts
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import Constants from 'expo-constants';
|
||||||
|
import * as Device from 'expo-device';
|
||||||
|
import * as Notifications from 'expo-notifications';
|
||||||
|
import { Platform } from "react-native";
|
||||||
|
|
||||||
|
export async function registerForPushNotificationsAsync() {
|
||||||
|
if (Platform.OS === 'android') {
|
||||||
|
await Notifications.setNotificationChannelAsync('default', {
|
||||||
|
name: 'default',
|
||||||
|
importance: Notifications.AndroidImportance.MAX,
|
||||||
|
vibrationPattern: [0, 250, 250, 250, 250, 250, 250, 250, 500],
|
||||||
|
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') {
|
||||||
|
throw new Error('Permission not granted')
|
||||||
|
}
|
||||||
|
|
||||||
|
const projectId = Constants?.expoConfig?.extra?.eas?.projectId ?? Constants?.expoConfig?.extra?.projectId
|
||||||
|
if (!projectId) {
|
||||||
|
throw new Error('Project ID not found')
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const pushTokenString = (await Notifications.getExpoPushTokenAsync({ projectId })).data
|
||||||
|
console.log(pushTokenString)
|
||||||
|
return pushTokenString
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(`Error getting push token: ${error}`)
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
throw new Error('Must use physical device for Push Notifications')
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,6 +30,8 @@
|
|||||||
"expo-blur": "~14.1.4",
|
"expo-blur": "~14.1.4",
|
||||||
"expo-clipboard": "^7.1.4",
|
"expo-clipboard": "^7.1.4",
|
||||||
"expo-constants": "~17.1.6",
|
"expo-constants": "~17.1.6",
|
||||||
|
"expo-dev-client": "~5.2.0",
|
||||||
|
"expo-device": "~7.1.4",
|
||||||
"expo-document-picker": "^13.1.5",
|
"expo-document-picker": "^13.1.5",
|
||||||
"expo-file-system": "^18.1.10",
|
"expo-file-system": "^18.1.10",
|
||||||
"expo-font": "~13.3.1",
|
"expo-font": "~13.3.1",
|
||||||
@@ -39,6 +41,8 @@
|
|||||||
"expo-linear-gradient": "~14.1.4",
|
"expo-linear-gradient": "~14.1.4",
|
||||||
"expo-linking": "~7.1.5",
|
"expo-linking": "~7.1.5",
|
||||||
"expo-media-library": "~17.1.6",
|
"expo-media-library": "~17.1.6",
|
||||||
|
"expo-modules-core": "~2.4.0",
|
||||||
|
"expo-notifications": "~0.31.3",
|
||||||
"expo-router": "~5.0.7",
|
"expo-router": "~5.0.7",
|
||||||
"expo-sharing": "^13.1.5",
|
"expo-sharing": "^13.1.5",
|
||||||
"expo-splash-screen": "~0.30.8",
|
"expo-splash-screen": "~0.30.8",
|
||||||
|
|||||||
89
providers/NotificationProvider.tsx
Normal file
89
providers/NotificationProvider.tsx
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
import { registerForPushNotificationsAsync } from "@/lib/registerForPushNotificationsAsync";
|
||||||
|
import { Subscription } from "expo-modules-core";
|
||||||
|
import * as Notifications from "expo-notifications";
|
||||||
|
import React, {
|
||||||
|
createContext,
|
||||||
|
ReactNode,
|
||||||
|
useContext,
|
||||||
|
useEffect,
|
||||||
|
useRef,
|
||||||
|
useState,
|
||||||
|
} from "react";
|
||||||
|
|
||||||
|
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<Subscription>();
|
||||||
|
const responseListener = useRef<Subscription>();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
registerForPushNotificationsAsync().then(
|
||||||
|
(token) => setExpoPushToken(token),
|
||||||
|
(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
|
||||||
|
});
|
||||||
|
|
||||||
|
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>
|
||||||
|
);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user