Data not inserting into Firebase Database - javascript

I am tring to insert a record from my react native app to Firebase.
And my code as follow:
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import * as firebase from 'firebase';
var React = require('react-native');
var {
Component,
AppRegistry,
StyleSheet,
Text,
View,
TouchableHighlight,
TextInput,
ListView
} = React;
var Firebase = require('firebase');
export default class App extends React.Component {
constructor(props) {
super(props);
var myFirebaseRef = new Firebase('https://test.firebaseio.com/');
myFirebaseRef.set({
title: "Hello World!",
author: "Simon",
location: {
city: "Muenster",
state: "Germany",
zip: 48155
}
});
}
render() {
return (
<View style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
AppRegistry.registerComponent('devdacticFirebase', () => devdacticFirebase);
However, when I launch the app, the record is not inserting into my Firebase. It never throw me any error message also. Why is it so? Which part am I missing out?

You're mixing es5 & es6 code. Since you've already import firebase, you don't need to require it.
REFERENCE
In ES5, if you use CommonJS standard, the introduction of React package through basic require, the code is similar to this:
var ReactNative = require("react-native");
var {Image,Text} = ReactNative;
In ES6, the import wording is more standard similar to this:
import { Image, Text} from 'react-native'
Recently firebase has updated their web SDK, which changed some of its API. The syntax you're using looks like the 2.x API, while the latest version is pretty different
Please initialize the firebase once the app is loaded (recommend in componentWillMount method) so that you can use it everywhere in the code
componentWillMount() {
var config = {
"apiKey": "YOUR_API_KEY",
"authDomain": "YOUR_FB_DOMAIN",
"databaseURL": "YOUR_FIREBASE_URL",
"projectId": "YOUR_FB_PROJECT_ID"
}
firebase.initializeApp(config);
}
UPDATE
It is weird when you put firebase set in the constructor. I guess you want to add new record to the firebase, you can use set with push(), this will add new record. Let say you have user table in the database, so :
import {TouchableOpacity} from 'react-native';
export default class App extends React.Component {
componentWillMount() {
var config = {
apiKey: "...",
authDomain: "...",
databaseURL: "...",
projectId: "...",
storageBucket: "...",
messagingSenderId: "..."
};
firebase.initializeApp(config);
}
constructor(props) {
super(props);
}
insert = () => {
firebase.database().ref('user').push().set({
title: "Hello World!",
author: "Simon",
location: "Germany",
city: "Muenster",
state: "Germany",
zip: 48155
}, (error) => {
if (error) {
console.log(error.message);
} else {
// Success
}
});
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={()=> this.insert()}>
<Text>Hello World!</Text>
</TouchableOpacity>
</View>
);
}
}

Related

Unable to read data from Firebase Realtime Database in React Native

I am working on a simple React Native app to read and write data from a Firebase database. My read and write permissions in Firebase have been set to true:
{
"rules": {
".read": true,
".write": true,
}
}
Here are my relevant files:
App.js
import React from 'react'
import {View, StyleSheet, Button} from 'react-native'
import * as firebase from 'firebase'
import RootStackNavigator from './navigation/RootNavigation'
export default class App extends React.Component {
constructor(props) {
super(props)
this.state = {
isLoadingComplete: false
}
var firebaseConfig = {
apiKey: "xxxxxxx",
authDomain: "testproject-9d0bc.firebaseapp.com",
databaseURL: "https://testproject-9d0bc-default-rtdb.firebaseio.com",
projectId: "testproject-9d0bc",
storageBucket: "testproject-9d0bc.appspot.com",
messagingSenderId: "1003049293166",
appId: "1:1003049293166:web:1df37fd6d181cf895cdd7f"
};
if (!firebase.apps.length) {
firebase.initializeApp(firebaseConfig)
} else {
firebase.app()
}
}
render() {
return (
<View style={styles.container}>
<RootStackNavigator/>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
});
RootStackNavigation.js
import React from 'react';
import { createAppContainer, StackNavigator } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
import HomeScreen from '../src/screens/HomeScreen';
const RootStackNavigator = createStackNavigator(
{
screen: HomeScreen
},
{
initialRouteName:"screen", // first component that should be displayed
defaultNavigationOptions: {
title: "App"
}
}
);
export default createAppContainer(RootStackNavigator)
HomeScreen.js
import React from "react";
import { Text, StyleSheet, View, Button, TouchableOpacity } from "react-native";
import * as firebase from "firebase";
const HomeScreen = (
props
) => {
function getData() {
firebase
.database()
.ref("people/")
.on("value", (snapshot) => {
const age = snapshot.val().age;
console.log("Age: " + age);
});
}
return (
<View>
<Text>Hello this is the home screen</Text>
<Button title="Get Data" onPress={getData} />
</View>
);
};
const styles = StyleSheet.create({
text: {
fontSize: 30,
},
});
export default HomeScreen;
My firebase database looks like this (all data was manually added through the firebase website)and I want to be able to print out these items after pressing the "Get Data" button to the console as shown in my getData function in HomeScreen.js
However, my code in getData does not work and nothing prints out to my console. What am I missing here?
Kindly modify this in your code
firebase.database.ref("people").on("value", snapshots => {
let peoples = [];
snapshots.forEach((snapshot) => {
peoples.push(snapshot.val().age);
console.log(snapshot.val().age);
});
// here you can set this Array
// setPeople(peoples)
Figured out my issue. As you can see in my firebase database, the way I was accessing my data was wrong. If I wanted to get the age of "dad", I should have called snapshot.val().dad.

Reading a specific data from firestore document and placing it as a text component

I am currently learning how to implement firestore into a react native expo project and I am just getting started. Firstly, I updated a specific data to a document in my firestore and now I am reading it into the log console, which is the code below.
However, I wish to read only a specific data of the document, such as "height", and place it in the Text component below. Unfortunatly my attempts were unsuccessfull. Could you give me a little help here?
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import * as firebase from 'firebase';
import 'firebase/firestore';
var firebaseConfig = {
apiKey: "****",
authDomain: "****",
databaseURL: "****",
projectId: "****",
storageBucket: "****",
messagingSenderId: "****",
appId: "****"
};
//Initialize firebase
if (!firebase.apps.length) {
//If app hasn't initialize, initialize app
firebase.initializeApp(firebaseConfig);
}
export default class App extends React.Component{
componentDidMount() {
var db = firebase.firestore();
var docRef = db.collection("users");
let getDoc = docRef.doc('Tiago').get()
.then(doc => {console.log('Document data:', doc.data())});
}
render(){
return (
<View style={styles.container}>
<Text>I wish to place it here</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
Plus, I can't really find a complete documentation on how to implement firestore/firebase into a react native + expo project. Could you leave a link below so I can learn from?
You'll use state to get the value from componentDidMount to the render method.
export default class App extends React.Component{
componentDidMount() {
var db = firebase.firestore();
var docRef = db.collection("users");
let getDoc = docRef.doc('Tiago').get().then(doc => {
console.log('Document data:', doc.data())
setState({ height: doc.data().height });
});
}
render(){
return (
<View style={styles.container}>
<Text>{this.state.height}</Text>
</View>
);
}
}
Also see:
the React documentation on state and lifecycle.
It was a missing this. to render the method.
export default class App extends React.Component{
componentDidMount() {
var db = firebase.firestore();
var docRef = db.collection("users");
let getDoc = docRef.doc('Tiago').get().then(doc => {
console.log('Document data:', doc.data())
this.setState({ height: doc.data().height });
});
}
render(){
return (
<View style={styles.container}>
<Text>{this.state.height}</Text>
</View>
);
}
}

How to use react navigation outside of a screen

I would like to make my app move to the next page when a code is entered correctly, but I have been having much trouble doing so. I am working in a file names AccessForm.js , which is not a screen but is a component that is included in the access code screen. I tried using this.props.navigation.navigate('CreateAccountScreen');, but ran into the error "Undefined is not an object (evaluating 'this.props.navigation'). With some trial and error, I found out that I can only use react-navigation inside of an actual screen for some weird reason. After this, I made an attempt to use this.state and this.setState({})to keep track of a screen variable, and sync it to the actual access code screen, so i could use navigation. Unfortunately, this.setState also throws a "Undefined is not an object" error. I have pasted an abbreviated version of my code below. What would be the best way to achieve this navigating outside of a screen file issue?
App.js ---->
import { createStackNavigator, createAppContainer } from 'react-navigation';
import AccessScreen from './src/screens/AccessScreen';
import CreateAccountScreen from './src/screens/CreateAccountScreen';
const RootStack = createStackNavigator ({
EnterAccessCode : {
screen: AccessScreen
},
CreateAccount : {
screen: CreateAccountScreen
}
},
{
headerMode: 'none'
});
const App = createAppContainer(RootStack);
export default App;
AccessForm.js ---->
import React from 'react';
import { StyleSheet, Text, View, TextInput, AlertIOS } from 'react-native';
var firebase = require("firebase");
if (!firebase.apps.length) { // Don't open more than one firebase session
firebase.initializeApp({ // Initialize firebase connection
apiKey: "key",
authDomain: "domain",
databaseURL: "url",
storageBucket: "storage_bucket",
});
}
this.codesRef = firebase.database().ref('codes'); // A reference to the codes section in the db
// this.state = {
// screen: 0
// };
export default class LoginForm extends React.Component {
constructor(props) {
super(props);
//this.checkCode = this.checkCode.bind(this); // throws error
}
render() {
return (
<View style={styles.container} >
<TextInput
style={styles.input}
placeholder='Access Code'
returnKeyType='go'
onSubmitEditing={(text) => checkCode(text.nativeEvent.text)} // Checks the code entered
autoCapitalize='none'
autoCorrect={false}
/>
</View>
);
}
}
function checkCode(text) {
var code = text; // Set entered code to the var "code"
var identifier = ""; // Used to store unique code object identifier
codesRef.once('value', function(db_snapshot) {
let codeIsFound = false
db_snapshot.forEach(function(code_snapshot) { // Cycle through available codes in db
if (code == code_snapshot.val().value) { // Compare code to db code
codeIsFound = true;
identifier = code_snapshot.key; // Code object ID
}
})
if (codeIsFound) {
deleteCode(identifier); // Delete the code if used, maybe do this after account is created?
this.props.navigation.navigate('CreateAccountScreen');
//this.setState({screen: 1}); // this throws error
// MOVE TO NEXT SCREEN
//this.props.navigation.navigate('AccountCreateScreen'); // throws error
} else { // wrong code
// note to self : add error message based on state var
AlertIOS.alert("We're Sorry...", "The code you entered was not found in the database! Please contact Mr. Gibson for further assistance.");
}
});
}
function deleteCode(id) { // delete a code from unique ID
firebase.database().ref('codes/' + id).remove();
}
// stylesheet is below
Login.js ---->
import React from 'react';
import { StyleSheet, Text, View, Image, TextInput, KeyboardAvoidingView, Platform } from 'react-native';
import AccessForm from './AccessForm';
export default class App extends React.Component {
render() {
return (
<View>
<View style={styles.logoContainer}>
<Image
source={require('../images/mhs.jpg')}
style={styles.logo}
/>
<Text style={styles.app_title}>MHS-Protect</Text>
<Text>An app to keep MHS safe and in-touch.</Text>
</View>
<KeyboardAvoidingView style={styles.container} behavior='padding'>
<View style ={styles.formContainer}>
<AccessForm/>
</View>
</KeyboardAvoidingView>
</View>
);
}
}
//styles below
import React from 'react';
import { StyleSheet, Text, View, TextInput, AlertIOS } from 'react-native';
var firebase = require('firebase');
if (!firebase.apps.length) {
// Don't open more than one firebase session
firebase.initializeApp({
// Initialize firebase connection
apiKey: 'key',
authDomain: 'domain',
databaseURL: 'url',
storageBucket: 'storage_bucket',
});
}
export default class LoginForm extends React.Component {
constructor(props) {
super(props);
this.codesRef = firebase.database().ref('codes'); // A reference to the codes section in the db
}
checkCode = text => {
var code = text; // Set entered code to the var "code"
var identifier = ''; // Used to store unique code object identifier
this.codesRef.once('value', function(db_snapshot) {
let codeIsFound = false;
db_snapshot.forEach(function(code_snapshot) {
// Cycle through available codes in db
if (code == code_snapshot.val().value) {
// Compare code to db code
codeIsFound = true;
identifier = code_snapshot.key; // Code object ID
}
});
if (codeIsFound) {
this.deleteCode(identifier); // Delete the code if used, maybe do this after account is created?
this.props.navigation.navigate('CreateAccount');
} else {
// wrong code
// note to self : add error message based on state var
AlertIOS.alert(
"We're Sorry...",
'The code you entered was not found in the database! Please contact Mr. Gibson for further assistance.'
);
}
});
};
deleteCode = id => {
firebase
.database()
.ref('codes/' + id)
.remove();
};
render() {
return (
<View style={styles.container}>
<TextInput
style={styles.input}
placeholder="Access Code"
returnKeyType="go"
onSubmitEditing={text => this.checkCode(text.nativeEvent.text)} // Checks the code entered
autoCapitalize="none"
autoCorrect={false}
/>
</View>
);
}
}
You should have navigation object in your props. By default, react navigation will pass navigation to all screens but other components. To do this, you have two options:
1. Pass navigation props from your screen to every child components (not recommended).
2. Use withNavigation as mention in document here https://reactnavigation.org/docs/en/connecting-navigation-prop.html
import React from 'react';
import { Button } from 'react-native';
import { withNavigation } from 'react-navigation';
class MyBackButton extends React.Component {
render() {
return <Button title="Back" onPress={() => { this.props.navigation.goBack() }} />;
}
}
// withNavigation returns a component that wraps MyBackButton and passes in the
// navigation prop
export default withNavigation(MyBackButton);
Edit:
The checkCode method does not belong to your LoginForm. You need to:
1. Make it part of LoginForm .
2. Remember to use bind or arrow function definition. Otherwise, your this inside function is not defined.
import { withNavigation } from 'react-navigation';
class LoginForm extends React.Component {
checkCode = (text) => {
....
};
}
export default withNavigation(LoginForm);
You can read more about bind or arrow method here https://medium.com/shoutem/react-to-bind-or-not-to-bind-7bf58327e22a
Copy and paste(Reference) from: https://github.com/react-navigation/react-navigation/issues/1439#issuecomment-303661539
It works from me.
you can pass your top-level navigator ref to a service, and dispatch actions from that service.
// App.js
import NavigatorService from './services/navigator';
const Navigator = StackNavigator({ /* ... */ })
class App extends Component {
// ...
render(): {
return (
<Navigator
ref={navigatorRef => {
NavigatorService.setContainer(navigatorRef);
}}
/>
);
}
}
// services/navigator.js
// #flow
import { NavigationActions } from 'react-navigation';
import type { NavigationParams, NavigationRoute } from 'react-navigation';
let _container; // eslint-disable-line
function setContainer(container: Object) {
_container = container;
}
function reset(routeName: string, params?: NavigationParams) {
_container.dispatch(
NavigationActions.reset({
index: 0,
actions: [
NavigationActions.navigate({
type: 'Navigation/NAVIGATE',
routeName,
params,
}),
],
}),
);
}
function navigate(routeName: string, params?: NavigationParams) {
_container.dispatch(
NavigationActions.navigate({
type: 'Navigation/NAVIGATE',
routeName,
params,
}),
);
}
function navigateDeep(actions: { routeName: string, params?: NavigationParams }[]) {
_container.dispatch(
actions.reduceRight(
(prevAction, action): any =>
NavigationActions.navigate({
type: 'Navigation/NAVIGATE',
routeName: action.routeName,
params: action.params,
action: prevAction,
}),
undefined,
),
);
}
function getCurrentRoute(): NavigationRoute | null {
if (!_container || !_container.state.nav) {
return null;
}
return _container.state.nav.routes[_container.state.nav.index] || null;
}
export default {
setContainer,
navigateDeep,
navigate,
reset,
getCurrentRoute,
};
and then you can use Navigator service everywhere.
Like:
import NavigatorService from './services/navigator';
NavigatorService.navigate('Home');

Undefined ' this.props.navigation.state.props.p' navigation react-native

I have read all the other topics about this issue, but no one is the solution to my problem.
I don't know why, but I can't pass props to react-navigation when I try to navigate, I always get this error:
"Undefined ' this.props.navigation.state.props.p'"
There is my code:
import React from 'react'
import {View, Text, ActivityIndicator, StyleSheet} from 'react-native'
import * as firebase from 'firebase';
const config = {
apiKey: "AIzaSyBeFuR40n7vp1XU9edL8PeOFq3UafKQ314",
authDomain: "anylibrary-961e1.firebaseapp.com",
databaseURL: "https://anylibrary-961e1.firebaseio.com",
projectId: "anylibrary-961e1",
storageBucket: "anylibrary-961e1.appspot.com",
messagingSenderId: "482573837189"
};
export default class Loading extends React.Component {
static navigationOptions = {
header: null,
};
constructor(props) {
super(props);
}
componentWillMount() {
if (!firebase.apps.length) {
firebase.initializeApp(config);
}
}
componentDidMount() {
firebase.auth().onAuthStateChanged(user => {
const {navigate} = this.props.navigation;
if (user) {
navigate('UserArea', {p: 'Profile'});
} else {
navigate('MainPage');
}
})
}
render() {
return (
<View style={styles.container}>
<Text>Loading...</Text>
<ActivityIndicator size="large"/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}
})
And:
import React from 'react';
import {StyleSheet, View, Alert} from 'react-native';
import Profile from './Profile';
import Notifications from './Notifications';
import Search from './Search';
import Home from './Home';
import Tabbar from 'react-native-tabbar-bottom'
import * as firebase from 'firebase';
const config = {
apiKey: "AIzaSyBeFuR40n7vp1XU9edL8PeOFq3UafKQ314",
authDomain: "anylibrary-961e1.firebaseapp.com",
databaseURL: "https://anylibrary-961e1.firebaseio.com",
projectId: "anylibrary-961e1",
storageBucket: "anylibrary-961e1.appspot.com",
messagingSenderId: "482573837189"
};
export default class UserArea extends React.Component {
static navigationOptions = {
header: null,
}
constructor(props) {
super(props);
this.state = {
page: this.props.navigation.state.props.p,
name: '',
}
}
componentWillMount(){
if (!firebase.apps.length) {
firebase.initializeApp(config);
}
}
componentDidMount() {
firebase.auth().onAuthStateChanged(user => {
this.state.name = user.displayName;
})
}
render() {
return (
<View style={styles.container}>
{this.state.page === "Home" && <Home navigation={this.props.navigation}>Home</Home>}
{this.state.page === "Profile" && <Profile navigation={this.props.navigation}>Profile</Profile>}
{this.state.page === "Notifications" && <Notifications navigation={this.props.navigation}>Notifications</Notifications>}
{this.state.page === "Search" && <Search navigation={this.props.navigation}>Search</Search>}
<Tabbar
stateFunc={(tab) => {
this.setState({page: tab.page})
//this.props.navigation.setParams({tabTitle: tab.title})
}}
activePage={this.state.page}
tabbarBgColor='#00619A'
iconColor='#99c2ff'
tabs={[
{
page: "Home",
icon: "home",
iconText: "Home"
},
{
page: "Profile",
icon: "person",
iconText: "Profile"
},
{
page: "Notifications",
icon: "notifications",
badgeNumber: 0,
iconText: "Notifications"
},
{
page: "Search",
icon: "search",
iconText: "Search"
},
]}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1
}
});
Basically i send it like that:
navigate('UserArea', {p: 'Profile'});
and try to acces it like that:
page: this.props.navigation.state.props.p,
Anyone?
Where is the problem?
What I am doing wrong?
from the documentation this looks like the correct way to get the route params
this.props.navigation.state.params.p
https://reactnavigation.org/docs/en/navigation-prop.html
old method is
this.props.navigation.state.params
new method is
this.props.route.params
im using rn version 0.62,
react navigation version -5
try this one:
page: this.props.navigation.state.p
i advise you to use getParam - Get a specific param value with a fallback
const name = this.props.navigation.getParam('name', 'Peter');
if name or param are undefined, set the fallback to Peter.
If using react-navigation v5, use
const data = route.params?.someParam ?? 'defaultValue';

Need to specify screen react native tabnavigator

Problem
I made a very basic app using React Native, and now I want to have multiple tabs. When I tried to add a feed and comments tab, I get an error saying:
Uncaught Error: Route 'Feed' should declare a screen.
For example:
import MyScreen from './MyScreen'
...
Feed: {
Screen: MyScreen,
}
I don't know why I am getting this error, since the first class I call is the 'App' screen, which is what I named the screen. I would love some help getting this tab error fixed. Thank you!
Code
import React, { Component } from 'react';
import { StyleSheet, Text, View, Image, TextInput, ScrollView, TouchableHighlight, Button, FlatList } from 'react-native';
import { Font } from 'expo';
import * as firebase from 'firebase';
import { TabNavigator } from 'react-navigation';
const firebaseConfig = {
apiKey: "API-key",
authDomain: "candidtwo.firebaseapp.com",
databaseURL: "https://candidtwo.firebaseio.com",
storageBucket: "candidtwo.appspot.com",
};
const MyApp = TabNavigator({
Feed: {
screen: App,
},
CommentScreen: {
screen: Comments,
},
}, {
tabBarPosition: 'top',
animationEnabled: true,
tabBarOptions: {
activeTintColor: '#fe8200',
},
});
const firebaseApp = firebase.initializeApp(firebaseConfig);
var fontLoaded = false;
var ref = firebase.database().ref('posts');
var brightColor = ['#ffffff'];
var darkColor = ['#D3D3D3'];
var animalNames = ['WittyRhino','FriendlyRhino'];
var newPostRef = ref.push();
var postWidth = 360;
class App extends React.Component {
static navigationOptions = {
tabBarLabel: 'Home',
};
//App Code
}
class Comments extends React.Component {
static navigationOptions = {
tabBarLabel: 'Notifications',
};
render() {
return (
<Button
onPress={() => this.props.navigation.navigate('App')}
title="Go to notifications"
/>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 8,
backgroundColor: '#e8e8e8',
alignItems: 'center'
},
button: {
flex: 1,
backgroundColor: '#e8e8e8',
alignItems: 'center'
},
});
Define App and Comments components before
const MyApp = TabNavigator(...)
Hope this will help.

Categories

Resources