├── .gitattributes ├── .gitignore ├── App.tsx ├── LICENSE ├── NotifeeApp.tsx ├── README.md ├── index.js ├── make-demo.sh ├── notifee-demo.sh ├── patches ├── .gitkeep └── @react-native-community+cli-platform-apple+18.0.0.patch └── rnfbdemo.entitlements /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | 3 | *.sh text eol=lf 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | ios/pods/ 25 | 26 | # Android/IntelliJ 27 | # 28 | build/ 29 | .idea 30 | .gradle 31 | local.properties 32 | *.iml 33 | android/app/src/main/assets 34 | android/app/src/main/res/drawable-mdpi 35 | 36 | # node.js 37 | # 38 | node_modules/ 39 | npm-debug.log 40 | yarn-error.log 41 | 42 | # BUCK 43 | buck-out/ 44 | \.buckd/ 45 | *.keystore 46 | 47 | # fastlane 48 | # 49 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 50 | # screenshots whenever they are needed. 51 | # For more information about the recommended setup visit: 52 | # https://docs.fastlane.tools/best-practices/source-control/ 53 | 54 | */fastlane/report.xml 55 | */fastlane/Preview.html 56 | */fastlane/screenshots 57 | 58 | # Bundle artifact 59 | *.jsbundle 60 | 61 | # Firebase 62 | google-services.json* 63 | GoogleService-Info.plist* 64 | 65 | # Example 66 | rnfbdemo 67 | notifeedemo 68 | notifeewebdemo -------------------------------------------------------------------------------- /App.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * 5 | * @format 6 | */ 7 | 8 | import React, {useEffect, useState} from 'react'; 9 | import type {PropsWithChildren} from 'react'; 10 | import { 11 | Button, 12 | SafeAreaView, 13 | ScrollView, 14 | StatusBar, 15 | StyleSheet, 16 | Text, 17 | useColorScheme, 18 | View, 19 | } from 'react-native'; 20 | 21 | import {Colors, Header} from 'react-native/Libraries/NewAppScreen'; 22 | 23 | import {getApp, getApps} from '@react-native-firebase/app'; 24 | import {getAnalytics} from '@react-native-firebase/analytics'; 25 | import appCheck, {initializeAppCheck} from '@react-native-firebase/app-check'; 26 | import {getAppDistribution} from '@react-native-firebase/app-distribution'; 27 | import { 28 | connectAuthEmulator, 29 | FirebaseAuthTypes, 30 | getAuth, 31 | onAuthStateChanged, 32 | signInAnonymously, 33 | signOut, 34 | } from '@react-native-firebase/auth'; 35 | import {getCrashlytics} from '@react-native-firebase/crashlytics'; 36 | import {getDatabase} from '@react-native-firebase/database'; 37 | import {getDynamicLinks} from '@react-native-firebase/dynamic-links'; 38 | import {getFirestore} from '@react-native-firebase/firestore'; 39 | import {getFunctions} from '@react-native-firebase/functions'; 40 | import {getInAppMessaging} from '@react-native-firebase/in-app-messaging'; 41 | import {getInstallations} from '@react-native-firebase/installations'; 42 | import { 43 | getMessaging, 44 | getToken, 45 | isDeviceRegisteredForRemoteMessages, 46 | onMessage, 47 | registerDeviceForRemoteMessages, 48 | requestPermission, 49 | } from '@react-native-firebase/messaging'; 50 | import {getPerformance} from '@react-native-firebase/perf'; 51 | import {getRemoteConfig} from '@react-native-firebase/remote-config'; 52 | import {getStorage} from '@react-native-firebase/storage'; 53 | import {getVertexAI} from '@react-native-firebase/vertexai'; 54 | 55 | type SectionProps = PropsWithChildren<{ 56 | title: string; 57 | }>; 58 | 59 | function Section({children, title}: SectionProps): JSX.Element { 60 | const isDarkMode = useColorScheme() === 'dark'; 61 | return ( 62 | 63 | 70 | {title} 71 | 72 | 79 | {children} 80 | 81 | 82 | ); 83 | } 84 | 85 | onMessage(getMessaging(), message => { 86 | console.log('messaging.onMessage received: ' + JSON.stringify(message)); 87 | }); 88 | 89 | connectAuthEmulator(getAuth(), 'http://localhost:9099'); 90 | 91 | onAuthStateChanged(getAuth(), (user: FirebaseAuthTypes.User) => { 92 | console.log( 93 | 'onAuthStateChanged was called with user uid ' + (user?.uid ?? '(no user)'), 94 | ); 95 | }); 96 | 97 | function App(): JSX.Element { 98 | const isDarkMode = useColorScheme() === 'dark'; 99 | const [appCheckPresent, setAppCheckPresent] = useState(false); 100 | 101 | useEffect(() => { 102 | console.log('initializating AppCheck...'); 103 | const rnfbProvider = appCheck().newReactNativeFirebaseAppCheckProvider(); 104 | rnfbProvider.configure({ 105 | android: { 106 | provider: __DEV__ ? 'debug' : 'playIntegrity', 107 | debugToken: 'invalid debug token', 108 | }, 109 | apple: { 110 | provider: __DEV__ ? 'debug' : 'appAttestWithDeviceCheckFallback', 111 | debugToken: 'invalid debug token', 112 | }, 113 | web: { 114 | provider: 'reCaptchaV3', 115 | siteKey: 'unknown', 116 | }, 117 | }); 118 | initializeAppCheck(getApp(), {provider: rnfbProvider}).then(() => { 119 | console.log('AppCheck is initialized.'); 120 | setAppCheckPresent(true); 121 | }); 122 | 123 | console.log('Requesting basic notification permission'); 124 | requestPermission(getMessaging(), {alert: true, badge: true}).then(() => 125 | console.log('Permission for notifications handled'), 126 | ); 127 | 128 | console.log('Initializing messaging for notifications...'); 129 | registerDeviceForRemoteMessages(getMessaging()) 130 | .then(() => 131 | console.log( 132 | 'Registered for remote messages: ' + 133 | isDeviceRegisteredForRemoteMessages(getMessaging()), 134 | ), 135 | ) 136 | .catch(e => 137 | console.error('could not register for remote notifications: ' + e), 138 | ); 139 | }, []); 140 | 141 | const backgroundStyle = { 142 | backgroundColor: isDarkMode ? Colors.darker : Colors.lighter, 143 | }; 144 | 145 | const dynStyles = StyleSheet.create({ 146 | colors: { 147 | color: isDarkMode ? Colors.white : Colors.black, 148 | }, 149 | }); 150 | 151 | const sendSilent = async () => { 152 | console.log('sending a silent notification now'); 153 | try { 154 | console.log('Getting our token for message send'); 155 | const token = await getToken(getMessaging()); 156 | console.log('sending a visible notification now'); 157 | const fcmRequest = await fetch( 158 | 'https://us-central1-react-native-firebase-testing.cloudfunctions.net/sendFCM', 159 | { 160 | method: 'POST', 161 | headers: { 162 | 'Content-Type': 'application/json', 163 | }, 164 | body: JSON.stringify({ 165 | data: { 166 | delay: 10000, 167 | message: { 168 | token, 169 | data: { 170 | message: 'hello from data block', 171 | }, 172 | apns: { 173 | payload: { 174 | aps: { 175 | 'content-available': 1, 176 | }, 177 | }, 178 | }, 179 | android: { 180 | priority: 'high', 181 | }, 182 | }, 183 | }, 184 | }), 185 | redirect: 'follow', 186 | }, 187 | ); 188 | console.log('request sent, waiting for response'); 189 | const {result} = await fcmRequest.json(); 190 | console.log('got sendFCM result: ' + JSON.stringify(result, null, 2)); 191 | } catch (e) { 192 | console.error('something went wrong? ' + e); 193 | } 194 | }; 195 | 196 | const sendVisible = async () => { 197 | try { 198 | console.log('Getting our token for message send'); 199 | const token = await getToken(getMessaging()); 200 | console.log('sending a visible notification now'); 201 | const fcmRequest = await fetch( 202 | 'https://us-central1-react-native-firebase-testing.cloudfunctions.net/sendFCM', 203 | { 204 | method: 'POST', 205 | headers: { 206 | 'Content-Type': 'application/json', 207 | }, 208 | body: JSON.stringify({ 209 | data: { 210 | delay: 10000, 211 | message: { 212 | token, 213 | notification: { 214 | title: 'hello world title', 215 | body: 'hello world body', 216 | }, 217 | data: { 218 | message: 'hello from data block', 219 | }, 220 | }, 221 | }, 222 | }), 223 | redirect: 'follow', 224 | }, 225 | ); 226 | console.log('request sent, waiting for response'); 227 | const {result} = await fcmRequest.json(); 228 | console.log('got sendFCM result: ' + JSON.stringify(result, null, 2)); 229 | } catch (e) { 230 | console.error('something went wrong? ' + e); 231 | } 232 | }; 233 | 234 | return ( 235 | 236 | 240 | 243 |