I'm trying to use Firebase realtime database on my React Native project. Based on the documentation I did following things on Android side(I'm checking for Android).
yarn add #react-native-firebase/app
Then put the google-services.json and did all gradle related changes.
yarn add #react-native-firebase/database
I have created a small test db as well to test the functionality.
This is the code that I have tried on my home page.
componentDidMount() {
console.log("Component Did Mount")
database()
.ref('name/')
.on('value', snapshot => {
console.log('User data: ', snapshot);
});
}
'User data' has not been printed in console. Not only the snapshot values but also user data text. Only 'component did mount' text is printed in console there. I added all the relevant permissions in AndroidMainifest as well
AndroidManifest
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
package json
"dependencies": {
"#react-native-async-storage/async-storage": "^1.15.5",
"#react-native-community/masked-view": "^0.1.11",
"#react-native-firebase/app": "^12.7.5",
"#react-native-firebase/database": "^12.7.5",
"#react-native-firebase/firestore": "^12.7.5",
"#react-native-firebase/remote-config": "^12.8.0",
"#react-navigation/bottom-tabs": "^5.11.11",
"#react-navigation/native": "^5.9.4",
"#react-navigation/stack": "^5.14.5",
"#reduxjs/toolkit": "^1.6.0",
"#thecodingmachine/redux-toolkit-wrapper": "2.0.1",
"axios": "^0.21.1",
"i18next": "^20.3.2",
"prop-types": "^15.7.2",
"react": "17.0.1",
"react-i18next": "^11.11.0",
"react-native": "0.64.2",
"react-native-flipper": "^0.94.1",
"react-native-gesture-handler": "^1.10.3",
"react-native-linear-gradient": "^2.5.6",
"react-native-reanimated": "^2.2.0",
"react-native-safe-area-context": "^3.2.0",
"react-native-screens": "^3.4.0",
"react-native-webview": "^11.13.0",
"react-redux": "^7.2.4",
"redux": "^4.1.0",
"redux-flipper": "^1.4.2",
"redux-persist": "^6.0.0"
},
"devDependencies": {
"#babel/core": "^7.12.9",
"#babel/runtime": "^7.12.5",
"#react-native-community/eslint-config": "^2.0.0",
"babel-jest": "^26.6.3",
"babel-plugin-module-resolver": "^4.0.0",
"eslint": "^7.22.0",
"eslint-import-resolver-babel-module": "^5.1.2",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-jest": "^24.3.5",
"identity-obj-proxy": "^3.0.0",
"jest": "^26.6.3",
"metro-react-native-babel-preset": "^0.64.0",
"react-test-renderer": "17.0.1"
},
I'm using this boilerplate
https://github.com/thecodingmachine/react-native-boilerplate
The DatabaseReference#on() method accepts two separate callbacks, one for when the requested event fires and one that handles errors.
database()
.ref('name') // no trailing "/"! (even though it does get trimmed off internally)
.on(
'value',
snapshot => {
console.log('Latest value for "/name": ', snapshot);
},
error => {
console.error('Failed to retrieve "/name": ', snapshot);
}
);
Importantly, this method also returns the first snapshot-listening callback, so that you can use it with DatabaseReference#off when unmounting your component.
const nameListener = database()
.ref('name')
.on(/* ... */);
// create a callback to be called in the `componentWillUnmount()` method
const unsubscribeNameListener = () => nameRef.off('value', nameListener);
Rolling this together gives:
class NameFromDatabase extends React.Component {
private unsubscribers = [];
componentDidMount() {
const nameRef = database().ref('name');
const nameListener = nameRef
.on(
'value',
snapshot => {
console.log('Latest value for "/name": ', snapshot);
},
error => {
console.error('Failed to retrieve "/name": ', snapshot);
}
);
// create a callback to be called in the `componentWillUnmount()` method
unsubscribers.push(() => nameRef.off('value', nameListener));
}
componentWillUnmount() {
unsubscribers.forEach(unsub => unsub());
}
}
Although the above code works, you really should make use of the React Hooks API and the new Firebase SDK's Modular API instead. Using the class-based form of React and namespace-based version of Firebase is ill-advised for new projects.
import { useState, useEffect } from 'react';
import { getDatabase, ref, onValue, off } from 'firebase/database';
const NameFromDatabase = () => {
const [name, setName] = useState();
useEffect(() => {
const nameRef = ref(getDatabase(), 'name');
// onValue returns its own unsubscribe function
return onValue(
nameRef,
snapshot => {
console.log('Latest value for "/name": ', snapshot.val());
setName(snapshot.val());
},
error => {
console.error('Failed to retrieve "/name": ', error);
setName(null);
}
);
}
if (name === void 0)
return (<div>Loading...</div>);
if (name === null)
return (<div class="error">Name not found!</div>);
return (<div>{ name }</div>);
}
Related
I have a simple react-native app that already has authentication working. The issue is, I am unable to read/write to my firebase Realtime DB.
The once and on methods do not execute any callback (nether successful or failed) even when there is data in the DB. However, if I do a set operation, the on/once methods return values. None of these values are reflected in the DB online, and these values do not persist when I delete the app data. Meaning, Realtime DB is only working locally, and not reflecting server side.
Notes:
Realtime DB is in us-central1
Rules are set to true for read and write
await reference.once('value') also did not work (never gets past this line)
Able to get correct reference object as google-services.json contains firebase url (see code)
I have firebase authentication working, so I am confident configuration steps are correct
Have rebuilt the app and ran gradle build after any android related changes
App.js:
import database from '#react-native-firebase/database';
const App = () => {
useEffect(() => {
const reference = database().ref('test');
console.log(reference); // LOGS CORRECT ADDRESS
reference.once( // NO VALUE RETURNED
'value',
(snapshot) => {
console.log('User data: ', snapshot.val());
},
(error) => {
console.log('error reading messages', error);
}
);
}, []);
return (
<IconComponentProvider IconComponent={MaterialCommunityIcons}>
{/* <AppProvider>
<NavigationStack />
</AppProvider> */}
</IconComponentProvider>
);
};
Realtime db values:
{
"test": "test" // exported from parent level
}
Realtime db rules:
{
"rules": {
".read": true,
".write": true,
}
}
Dependencies:
"dependencies": {
"#react-native-firebase/app": "^15.6.0",
"#react-native-firebase/auth": "^15.6.0",
"#react-native-firebase/database": "^15.6.0",
"#react-native-material/core": "^1.3.7",
"#react-navigation/bottom-tabs": "^6.3.3",
"#react-navigation/drawer": "^6.4.4",
"#react-navigation/native": "^6.0.12",
"#react-navigation/native-stack": "^6.8.0",
"eslint": "^7.32.0 || ^8.2.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-react-native": "^4.0.0",
"prettier": "^2.7.1",
"react": "18.0.0",
"react-native": "0.69.5",
"react-native-gesture-handler": "^2.6.0",
"react-native-reanimated": "^2.10.0",
"react-native-safe-area-context": "^4.3.3",
"react-native-screens": "^3.17.0",
"react-native-vector-icons": "^9.2.0",
"yarn": "^1.22.19"
},
added app/build.gradle dependencies:
implementation platform('com.google.firebase:firebase-bom:30.4.1')
implementation "com.google.firebase:firebase-core"
implementation "com.google.firebase:firebase-auth"
implementation "com.google.firebase:firebase-database"
app permissions:
<uses-permission android:name="android.permission.INTERNET" />
Can you try to initialize the database with the explicit path to it:
import database from '#react-native-firebase/database';
import firebase from '#react-native-firebase/app';
const db = firebase.app()
.database(
'https://<databaseName>.<region>.firebasedatabase.app'
);
the loading of fonts has not been working for several days and I cannot find the reason, and there is something else wrong with expo go, it takes a very long time to load, and for some reason after exp publish the application is not updated in any way, does anyone know the reason?
during development (6 months) there were no problems, but two days ago for some reason the fonts broke and I can't find the reason
if you remove the loading of fonts, then the application is loaded.
"expo-cli": "4.11.0",
"expo": "~40.0.0",
"expo-app-loading": "^1.0.1",
"react": "16.13.1",
"react-dom": "16.13.1",
"react-native": "https://github.com/expo/react-native/archive/sdk-40.0.1.tar.gz",
*In my case, when using expo go, I noticed that it takes a long time to load with AppLoading if the clocks(of my phone and my computer) are not in sync.
*IF it helps I'll show you How I load Fonts in my app, I am using currently using:
"expo": "^41.0.0",
"expo-app-loading": "^1.1.2",
"expo-font": "~9.1.0",
"react": "16.13.1",
"react-dom": "16.13.1",
"react-native": "https://github.com/expo/react-native/archive/sdk-41.0.0.tar.gz",
const fetchFonts = async () => {
return await Font.loadAsync({
'gotham-narrow-black':{
uri: require('./assets/fonts/gotham/GothamNarrow-Black.otf'),
display: Font.FontDisplay.FALLBACK
},
'gotham-narrow-book':{
uri: require('./assets/fonts/gotham/GothamNarrow-Book.otf'),
display: Font.FontDisplay.FALLBACK
},
'gotham-ultra':{
uri: require('./assets/fonts/gotham/Gotham-Ultra.otf'),
display: Font.FontDisplay.FALLBACK
},
'gotham-light':{
uri: require('./assets/fonts/gotham/GothamLight.otf'),
display: Font.FontDisplay.FALLBACK
},
'gotham-book':{
uri: require('./assets/fonts/gotham/Gotham-Book.otf'),
display: Font.FontDisplay.FALLBACK
},
})
}
export default function App() {
const [fontLoaded, setFontLoaded] = useState(false);
if(!fontLoaded) {
return <AppLoading
startAsync = { fetchFonts }
onError = { console.warn }
onFinish = { () => setFontLoaded(true) }
/>
}
return <MainApp />;
}
As your font is a static file you will have to change your fontLoading function
Change this
import Helvetica from './Helvetica.ttf';
const useFonts = async () =>
await Font.loadAsync({
Helvetica: Helvetica, // not like this
});
to this
const useFonts = async () =>
await Font.loadAsync({
Helvetica: require('./Helvetica.ttf'), // correct location
});
So in your case change your loadFonts function to this
const loadFonts = async () =>
await Font.loadAsync({
montserratRegular: require('./assets/Montserrat-Regular.ttf'),
montserratBold: require('./assets/Montserrat-Bold.ttf'),
montserratSemiBold: require('./assets/Montserrat-SemiBold.ttf'),
montserratMedium: require('./assets/Montserrat-Medium.ttf'),
});
I am using Ionic and React and trying to implement deeplinking I am using App.getLaunchUrl(); from capacitor, when App is not open in the background (Android platform) every thing works fine but when the App is open in the background it returns null, also I have tried getState() method to get the launchUrl when the App state has been change but it is not working.
These are the versions which I am using:
{
"#capacitor/android": "^2.1.0",
"#capacitor/core": "2.1.0",
"#capacitor/ios": "^2.1.0",
"#ionic-native/contacts": "^5.26.0",
"#ionic-native/core": "^5.26.0",
"#ionic-native/deeplinks": "^5.26.0",
"#ionic/app-scripts": "3.2.4",
"#ionic/pwa-elements": "^1.5.2",
"#ionic/react": "^5.1.0",
"#ionic/react-hooks": "0.0.8",
"#ionic/react-router": "^5.1.0",
"#testing-library/jest-dom": "^5.7.0",
"#testing-library/react": "^10.0.4",
"#testing-library/user-event": "^10.1.2",
"#types/jest": "^25.2.1",
"#types/lodash": "^4.14.153",
"#types/node": "^13.13.5",
"#types/react": "^16.9.35",
"#types/react-dom": "^16.9.8",
"#types/react-router": "^5.1.7",
"#types/react-router-dom": "^5.1.5",
"axios": "^0.19.2",
"cordova-plugin-contacts": "^3.0.1",
"ionic": "^5.4.16",
"ionic-plugin-deeplinks": "^1.0.20",
"ionicons": "^5.0.1",
"lodash": "^4.17.15",
"node-sass": "^4.14.1",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-router": "^5.2.0",
"react-router-dom": "^5.2.0",
"react-scripts": "3.4.1",
"short-unique-id": "^3.0.3",
"typescript": "3.8.3"
}
and this is the code I am using inside the App component which contains my Router.
import React, { useReducer, useEffect, useState } from "react";
import { Route, Redirect } from "react-router-dom";
import { IonApp, IonRouterOutlet } from "#ionic/react";
import { IonReactRouter } from "#ionic/react-router";
import Home from "./pages/Home/Home";
import InroPage from "./pages/IntroPage/IntroPage";
import Login from "./pages/Login/Login";
import Verfication from "./pages/Verification/Verifocation";
import Profile from "./pages/Profile/Profile";
import HomePage from "./pages/HomePage/HomePage";
import CircleDetail from "./pages/CircleDetail/CircleDetail";
import InvitationPage from "./pages/InvitationPage/InvitationPage";
import Actions, { Context, initialState, reducer } from "./state/globalState";
/* Core CSS required for Ionic components to work properly */
import "#ionic/react/css/core.css";
/* Basic CSS for apps built with Ionic */
import "#ionic/react/css/normalize.css";
import "#ionic/react/css/structure.css";
import "#ionic/react/css/typography.css";
/* Optional CSS utils that can be commented out */
import "#ionic/react/css/padding.css";
import "#ionic/react/css/float-elements.css";
import "#ionic/react/css/text-alignment.css";
import "#ionic/react/css/text-transformation.css";
import "#ionic/react/css/flex-utils.css";
import "#ionic/react/css/display.css";
/* Theme variables */
import "./theme/variables.css";
import "./styles/main.scss";
import { Plugins } from "#capacitor/core";
const { Storage } = Plugins;
const { App: CapApp } = Plugins;
const App: React.FC = () => {
// const history = useHistory();
const [hasData, setHasData] = useState(false);
const [URL, setURL]: any = useState(null);
const [store, dispatch] = useReducer(reducer, initialState);
const getObject = async () => {
const ret: any = await Storage.get({ key: "userData" });
const user = JSON.parse(ret.value);
return new Promise((resolve, reject) => {
resolve(user);
});
};
Plugins.App.addListener("appUrlOpen", (data: any) => {
console.log("from app URL in APP Component");
console.log(data);
const resultID = data.url.split("/")[data.url.split("/").length - 1];
setURL("/circle/" + resultID);
});
Plugins.App.addListener("appStateChange", async (state: any) => {
console.log("from app state change in APP Component", state);
const a = await Plugins.App.getLaunchUrl().then((ret) => {
console.log(ret);
if (ret.url !== "") {
const resultID = ret.url.split("/")[ret.url.split("/").length - 1];
setURL("/circle/" + resultID);
} else {
setURL(null);
}
});
setTimeout(() => {
console.log("in the settime out", a);
}, 2000);
});
useEffect(() => {
getObject().then((data: any) => {
// console.log(data);
if (data !== null) {
setHasData(true);
}
Plugins.App.getLaunchUrl().then((ret) => {
// console.log(ret);
if (ret.url !== "") {
// console.log("outside of useEffect");
// console.log(ret.url.split("/"));
const resultID = ret.url.split("/")[ret.url.split("/").length - 1];
setURL("/circle/" + resultID);
} else {
setURL(null);
}
});
// console.log(ret);
});
}, []);
return (
<Context.Provider value={{ store, dispatch }}>
<IonApp>
<IonReactRouter>
{/* <AppUrlListener></AppUrlListener> */}
{URL !== null && <Redirect to={URL} />}
<IonRouterOutlet>
<Route path="/circle/:id" component={InvitationPage} exact />
<Route exact path="/" component={hasData ? HomePage : InroPage} />
<Route exact path="/home-page" component={HomePage} />
<Route path="/login" component={Login} />
<Route path="/circle-detail/:id" component={CircleDetail} exact />
<Route path="/verification" component={Verfication} />
<Route path="/profile" component={Profile} />
<Route path="/home" component={Home} exact={true} />
</IonRouterOutlet>
</IonReactRouter>
</IonApp>
</Context.Provider>
);
};
export default App;
I tried to use the latest version of cordova-plugin-firebasex for my ionic3 app. I also did refer the ionic3 example for firebasex plugin. But after adding the code, I am getting the error as 'TypeError: Cannot read property 'getToken' of undefined'. Below is the code which I have used:
In my login.ts file:
if ( this.accessToken ) {
this.fireBaseService.getFirebaseXToken();
}
In my firebase-service.ts file===**====
export class FireBaseService {
protected token:any;
public firebasePlugin;
async getFirebaseXToken() {
let token;
this.firebasePlugin = (window).FirebasePlugin;
token = await this.firebasePlugin.getToken(token => {
console.log('Response from getToken===>>>>',token);
});
}
}
These are the specs for my ionic3 project:
"cordova": "^9.0.0",
"cordova-android": "8.1.0",
"cordova-plugin-firebasex": "^8.1.1",
"cordova-android-play-services-gradle-release": "3.0.0",
"cordova-android-support-gradle-release": "^3.0.0",
"cordova-plugin-androidx": "^1.0.2",
"cordova-plugin-androidx-adapter": "1.1.0",
"devDependencies": {
"#ionic/app-scripts": "^3.2.2",
"typescript": "~2.6.2"
}
If there are any changes to be done in my code, am I missing something, any kind of help will be helpful. Thanks.
I am currently creating a food ordering system and i am trying to set up firebase on a react-native project
The application lets me use authentication from firebase i can succesfully sign in and also register new users but it does not let me use firestore
i am trying to do a console log in the below code in my to see if the firestore will run with the application
below is a list of the app.js/the screen where i am calling the collection from firestore
the error reads as so
firebase error
//error reads on android emulator
the build.gradle app level and the
//list of packages used on for react
package.json
"name": "projectFinal",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start",
"test": "jest",
"lint": "eslint ."
},
"dependencies": {
"#react-native-community/masked-view": "^0.1.7",
"#react-native-firebase/app": "^6.3.4",
"#react-native-firebase/auth": "^6.3.4",
"#react-native-firebase/firestore": "^6.3.4",
"firebase": "^7.9.3",
"react": "16.9.0",
"react-native": "0.60.5",
"react-native-elements": "^1.2.7",
"react-native-gesture-handler": "^1.6.0",
"react-native-reanimated": "^1.7.0",
"react-native-safe-area-context": "^0.7.3",
"react-native-safe-area-view": "^1.0.0",
"react-native-screens": "^2.2.0",
"react-native-vector-icons": "^6.6.0",
"react-navigation": "^4.2.2",
"react-navigation-header-buttons": "^3.0.5",
"react-navigation-stack": "^2.2.2",
"react-navigation-tabs": "^2.8.2"
},
"devDependencies": {
"#babel/core": "^7.8.6",
"#babel/runtime": "^7.8.4",
"#react-native-community/eslint-config": "^0.0.7",
"babel-jest": "^25.1.0",
"eslint": "^6.8.0",
"jest": "^25.1.0",
"metro-react-native-babel-preset": "^0.58.0",
"react-test-renderer": "16.9.0"
},
"jest": {
"preset": "react-native"
}
}
app.js
import React, { Component } from 'react';
import { View, StyleSheet, Text } from 'react-native';
import {createAppContainer, createSwitchNavigator} from 'react-navigation';
import {createStackNavigator} from 'react-navigation-stack';
import {createBottomTabNavigator, createTabNavigator} from 'react-navigation-tabs'
import Icon from 'react-native-vector-icons/Ionicons'
import { HeaderButtons, HeaderButton, Item } from 'react-navigation-header-buttons';
import Home from './src/Screens/Home'
//import MyAccount from './Screens/MyAccount';
import Register from './src/Screens/Register'
import Login from './src/Screens/Login';
//import Menus from './Screens/Menus';
import LoadingScreen from './src/Screens/LoadingScreen';
// import Jitters from './Screens/Jitters';
// import Scullery from './Screens/Scullery';
// import Bunker from './Screens/TheBunker';
// import OrderDetails from './Screens/OrderDetails';
import ViewOrder from './src/Screens/ViewOrder';
import "firebase/firestore"
import firebase from "firebase"
import firestore from "#react-native-firebase/firestore"
//this is where firebase is initializedd the google.services json is also in the relevant file
const firebaseConfig = {
apiKey: "AIza<<redacted>>",
authDomain: "<<redacted>>.firebaseapp.com",
databaseURL: "https://<<redacted>>.firebaseio.com",
projectId: "<<redacted>>",
storageBucket: "<<redacted>>.appspot.com",
messagingSenderId: "<<redacted>>",
appId: "1:8<<redacted>>",
measurementId: "G-T<<redacted>>"
};
// Instantiate a Firebase app.
const firebaseApp = firebase.initializeApp(firebaseConfig);
const db = firebaseApp.firestore()
const TabNavigator = createBottomTabNavigator(
{
Home: {
screen: Home,
navigationOptions: {
TabBarIcon: ({ tintColor}) => <Ionicons name="ios-home" size={24} color={tintColor}/>
}
},
// Menus: {
// screen: Menus,
// navigationOptions: {
// TabBarIcon: ({ tintColor}) => <Ionicons name="ios-chatbox" size={24} color={tintColor}/>
// }
ViewOrder: {
screen: ViewOrder,
navigationOptions: {
TabBarIcon: ({ tintColor}) => <Ionicons name="ios-add-circle" size={24} color={tintColor}/>
},
}
},
{
tabBarOptions: {
activeTintColor: "#161F3D",
inactiveTintColor: "#E9446A",
showLabel: true
}
}
);
const authStack = createStackNavigator(
{
Home: Home,
Login: Login,
Register: Register,
// Menu: Menus,
// Jitters: Jitters,
// Scullery: Scullery,
// TheBunker: Bunker,
// MyAccount: MyAccount,
// OrderDetails: OrderDetails,
ViewOrder: ViewOrder
});
const App = createAppContainer(TabNavigator);
export default createAppContainer(
(
createSwitchNavigator({
Loading: LoadingScreen,
App: TabNavigator,
Auth: authStack
},
{
initalRouteName: "Loading Page"
}
)
)
);
##Screen to call a collection of firestore##
//this is a console log to see if firestore will initialize
import React, {useState} from 'react'
import {View, Text} from 'react-native'
import firebase from "firebase"
import firestore from "#react-native-firebase/firestore"
async function myFunction() {
var user = firebase.auth().currentUser;
let x = await firestore().collection("Users").doc("MmjyeGlhFPu0g6pK0GQ2").get();
// console.log(x)
}
export default class ViewOrder extends React.Component {
componentDidMount() {
myFunction(
)
}
render() {
return(
<View>
<Text>Hello</Text>
</View>
)}
**//error reads on android emulator**
as possible unhandled promise rejection (id:0)
error: no firebase app ['default] has been created - call
firebase.initalize.app() getapp#http://10.0.2.2.8081/index.bundle
?platform
It seems by the error, mainly for this below part:
Error: No Firebase App '[DEFAULT]' has been created - call firebase.initializeApp()
That you have not initialized your Firebase database. As informed in the documentation firebase. app. App, you need to call firebase.initializeApp() to create an app. Besides that, I would change your import to import * as firebase from "firebase", so you are importing all packages needed for Firebase.
I have checked all these below posts from the Community and these possible solutions that I provided you, are just some options and alternatives that might solve your case.
I would recommend you take a look at them, so you can get more information and check further since there might be some other structure and environment configurations that can be affecting you and these cases can assist you with it.
No Firebase App '[DEFAULT]' has been created - call Firebase App.initializeApp()
Firebase: No Firebase App '[DEFAULT]' has been created (Firestore)
Error: Firebase: No Firebase App '[DEFAULT]' has been created
Error: No Firebase App '[DEFAULT]' has been created - call Firebase App.initializeApp()
Let me know if the information helped you!