I'm using https://github.com/expo-community/expo-firebase-starter as a starter template to build a react native app using firebase.
I am working with the following file in Home.js and want to save data to firebase but am getting an error. The error.
firebase.database is not a function. (In 'firebase.database(reflection)', 'firebase.database' is undefined)
Here is the code I'm using. When someone writes a reflection, I'm trying to save that reflection text along with the user ID.
import React, {useEffect, useState } from "react";
import { StyleSheet, Text, View } from "react-native";
import { Container, Content, Header, Form, Input, Item, Label } from 'native-base';
import { Button } from "react-native-elements";
import { withFirebaseHOC } from "../config/Firebase";
import * as firebase from 'firebase';
import "firebase/database";
function Home({ navigation, firebase }) {
const [reflection, setReflection] = useState('');
const[member, setMember] = useState('');
useEffect(() => {
try {
firebase.checkUserAuth(user => {
if (user) {
// if the user has previously logged in
setMember(user);
console.log(member);
} else {
// if the user has previously logged out from the app
navigation.navigate("Auth");
}
});
} catch (error) {
console.log(error);
}
}, []);
async function postReflection() {
try {
await console.log(reflection);
await console.log(member.email);
firebase.database(reflection).ref('Posts/').set({
reflection,
}).then((data)=>{
//success callback
console.log('data ' , data)
}).catch((error)=>{
//error callback
console.log('error ' , error)
})
} catch (error) {
console.log(error);
}
}
async function handleSignout() {
try {
await firebase.signOut();
navigation.navigate("Auth");
} catch (error) {
console.log(error);
}
}
return (
<Container style={styles.container}>
<Form>
<Item floatingLabel>
<Label>Reflection</Label>
<Input
autoCapitalize='none'
autoCorrect={false}
onChangeText={text => setReflection(text)}
/>
</Item>
<Button style = {{ marginTop: 10, marginHorizontal:30 }}
title="Share"
rounded
onPress= {postReflection}
>
</Button>
</Form>
<Button
title="Signout"
onPress={handleSignout}
titleStyle={{
color: "#F57C00"
}}
type="clear"
/>
</Container>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
// justifyContent: "center"
}
});
export default withFirebaseHOC(Home);
Your /config/Firebase/firebase.js doesn't have a database property. Have a look at how the Firebase object is being exported.
// inside /config/Firebase/firebase.js
import "firebase/database"; // add this
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
const Firebase = {
// add this
database: () => {
return firebase.database()
}
};
export default Firebase;
Have a read of this step. You can't just import the part of the firebase library, you need to actually assign it to a variable and export it to use it.
https://firebase.google.com/docs/web/setup#namespace
Add the following after import * as firebase from 'firebase';
import "firebase/database";
Each Firebase product has separate APIs that must be added, as described in the documentation.
Related
Why my app is only showing loading screen? when i am running my app than its only loading and not showing other screens and showing a WARN that
` WARN Possible Unhandled Promise Rejection (id: 0): TypeError: undefined is
i think it has problem with this code
import React, { useEffect } from 'react';
import { View, ActivityIndicator, StyleSheet} from 'react-native';
import { AsyncStorage } from '#react-native-async-storage/async-storage';
import { useDispatch } from 'react-redux';
import Colors from '../constants/Colors';
import * as authActions from '../store/actions/auth';
const StartupScreen = props => {
const dispatch = useDispatch();
useEffect(() => {
const tryLogin = async () => {
const userData = await AsyncStorage.getItem('userData');
if (!userData) {
// props.navigation.navigate('Auth');
dispatch(authActions.setDidTryAutoLogin());
return;
}
const transformedData = JSON.parse(userData);
const { token, user } = transformedData;
// props.navigation.navigate('Shop');
dispatch(authActions.authenticate(user, token));
};
tryLogin();
}, [dispatch])
return (
<View style={styles.screen}>
<ActivityIndicator size="large" color={Colors.primary} />
</View>
);
};
const styles = StyleSheet.create({
screen: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
});
export default StartupScreen;
According to the docs you import is wrong.
This:
import { AsyncStorage } from '#react-native-async-storage/async-storage';
should be
import AsyncStorage from '#react-native-async-storage/async-storage';
Basically, what you are trying to do with {AsyncStorage} is you are importing "part" of the exported code called AsyncStorage. That is why the error says:
_asyncStorage.AsyncStorage.getItem') (asyncStorage mentioned twice) and you need the entire object out of the package.
I'm in the process of building a merch e-commerce website for a client utilizing the commerce.js API however I've run into a problem. When passing the "cart" object as a prop to the checkout file it returns as an empty object which breaks the website. The web application passes the "cart" object as a prop in other parts of the code and works just fine. Is there something I'm doing wrong?
Code for reference:
import React, { useState, useEffect } from 'react';
import {Paper, Stepper, Step, StepLabel, Typography, CircularProgress, Divider, Button} from '#material-ui/core';
import { commerce } from '../../../lib/commerce';
import Addressform from '../Addressform';
import Paymentform from '../Paymentform';
const steps =['Shipping Address', 'Payment details'];
const Checkout = ({ cart }) => {
const [activeStep, setActiveStep] = useState(0);
const [checkoutToken, setCheckoutToken] = useState(null);
useEffect (() => {
const generateToken = async () => {
console.log(cart.id);
// returns as undefined
try {
const token = await commerce.checkout.generateToken(cart.id, { type: 'cart' });
console.log(token);
setCheckoutToken(token);
console.log("Success!")
} catch (error) {
console.log(error); //Returns 404 Error Obv
console.log("Didnt work")
}
}
generateToken();
}, []);
const Confirmation = () => (
<>
Confirmation
</>
);
const Form = () => activeStep === 0
? <Addressform />
: < Paymentform />
return(
<>
...
</>
);
};
export default Checkout;
I am calling an API to do few actions.
I want to take the response of each action and show it inside Snackbar/alert.
I am able to show only the first response and nothing else even after iterating the messages in a map.
Here is my business logic calling the api
try {
const deletedUser = await deleteUser({ username: username });
[deletedUser.data.status.action1, deletedUser.data.status.action2].map(
(msg) =>
setNotify({
isOpen: true,
message: msg,
type: "success",
})
);
} catch (error) {}
setNotify will open the Snackbar with the alerts
import React from "react";
import { Snackbar, Alert } from "#mui/material";
import { styled } from "#mui/material/styles";
const StyledSnackbar = styled((props) => <Snackbar {...props} />)(
({ theme }) => ({
"& .MuiSnackbar-root": {
top: theme.spacing(15),
},
})
);
export default function Notification(props) {
const { notify, setNotify } = props;
const handleClose = (event, reason) => {
setNotify({
...notify,
isOpen: false,
});
};
return (
<StyledSnackbar
open={notify.isOpen}
autoHideDuration={10000}
anchorOrigin={{ vertical: "top", horizontal: "right" }}
onClose={handleClose}
>
<Alert severity={notify.type} onClose={handleClose}>
{notify.message}
</Alert>
</StyledSnackbar>
);
}
The only issue it's only displaying the first action and nothing else.
Edit On Sandbox
I suspect the alerts are overlapping on top of each other Maybe we need to add some sort of AutoGrow prop
You have to use notistack as described in the MUI doc:
This example demonstrates how to use notistack. notistack has an
imperative API that makes it easy to display snackbars, without having
to handle their open/close state. It also enables you to stack them on
top of one another (although this is discouraged by the Material
Design guidelines).
Start by wrapping your app inside a SnackbarProvider component then use useSnackbar hook to access enqueueSnackbar in order to add a snackbar to the queue to be displayed:
App.js
import "./styles.css";
import React from "react";
import { SnackbarProvider } from "notistack";
import Notification from "./Notification";
export default function App() {
return (
<SnackbarProvider maxSnack={3}>
<div className="App">
<h1>Dynamic Snackbar Alerts</h1>
<Notification />
</div>
</SnackbarProvider>
);
}
Notification.js
import React from "react";
import { Button } from "#mui/material";
import { useSnackbar } from "notistack";
export default function Notification(props) {
const { enqueueSnackbar } = useSnackbar();
const handleClick = async () => {
try {
const deletedUser = await deleteUser({ username: username });
[deletedUser.data.status.action1, deletedUser.data.status.action2].forEach((msg) => {
enqueueSnackbar(msg, {
variant: "success",
autoHideDuration: 10000,
anchorOrigin: { vertical: "top", horizontal: "right" }
});
});
} catch (error) {}
};
return (
<Button variant="outlined" onClick={handleClick}>
Generate Snackbar Dynamicly
</Button>
);
}
Demo:
I'm building a screen in React Native using expo. I'm new to both React Native and the Rematch framework, and I want to render the first and last names of the basketball players from this endpoint upon load: https://www.balldontlie.io/api/v1/players
Here's my models.js:
import axios from "axios";
export const players = {
state: {
players: [],
},
reducers: {
SET_PLAYERS: (state, payload) => {
return {
...state,
players: payload,
};
},
},
effects: (dispatch) => ({
async getPlayers() {
let response = await axios.get(
"https://www.balldontlie.io/api/v1/players"
);
let { data } = await response.json();
console.log(data);
dispatch.players.SET_PLAYERS(data);
},
}),
};
store.js
import { init } from "#rematch/core";
import * as models from "./models";
const store = init({ models });
export default store;
And finally, my main screen:
import { StatusBar } from "expo-status-bar";
import React from "react";
import { StyleSheet, Text, View } from "react-native";
import { Provider } from "react-redux";
import store from "./state_management/store";
export default function App() {
return (
<View style={styles.container}>
<Players />
<StatusBar style="auto" />
</View>
);
}
const Players = () => {
return (
<Provider store={store}>
// PLAYER LIST HERE!!
</Provider>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
});
Most examples I have seen online and on here are to do with onPress actions like increments, decrements etc. This involves managing data from an API call so I'm not sure what to do.
In main screen as you are using functional component try using useDispatch and useSelector to dispatch and fetch the list and map it to your screen
import { useDispatch, useSelector } from "react-redux";
const dispatch = useDispatch();
const responseList = useSelector(state => {
return state.apiReducer.data
})
In useEffect dispatch action to models
As from the question what i understand is a need of fetch the stored list from models and render players name, find code for the same in this link
Hi Everyone I am a newbie in React. I am building my react app with typescript and would like to add Stripe to do the online payment. But I cannot find the typescript tutorial on stripe, so I try to use javascript to write the stripe part. But when I trigger the stripe. The errors below appear:
Referring to other solutions on stackOverFlow, i have used different import methods like
import stripe from './stripe';
import * as stripe from './stripe';
but none of them can solve my problem.
What's wrong with my code?
Here are the codes:
For Stripe file:
import React from 'react'
import { Element } from "#stripe/react-stripe-js"
import { loadStripe } from '#stripe/stripe-js'
import "./Stripe.css"
const PaymentForm = require ('./PaymentForm.js')
const PUBLIC_KEY = "pk_test_XXXXXXX"
const stripeTestPromise = loadStripe(PUBLIC_KEY)
export default function Stripe() {
return (
<Element stripe={stripeTestPromise}>
<PaymentForm />
</Element>
)
}
For paymentFrom file:
import React, { useState } from 'react'
import { CardElement, useElements, useStripe } from "#stripe/react-stripe-js"
import * as axios from 'axios'
import "./Stripe.css"
const CARD_OPTIONS = {
iconStyle: "solid",
style: {
base: {
iconColor: "#c4f0ff",
color:"fff",
fontWeight: 500,
fontSize: "16px",
fontSmoothing:"antialiased",
},
invaild: {
iconColor: "#ffc7ee",
color: "ffc7ee"
}
}
}
export default function PaymentForm() {
const [success, setSuccess] = useState(false)
const stripe = useStripe()
const elements = useElements()
const handleSubmit = async (e) => {
e.preventDefault()
const { error, paymentMethod } = await stripe.createPaymentMethod({
type: "card",
card: elements.getElement(CardElement)
})
if (!error) {
try {
const { id } = paymentMethod
const response = await axios.post('http://localhost:8080/checkout', {
amount: 500,
id
})
if (response.data.success) {
console.log('Successful payment')
setSuccess(true)
}
} catch (error) {
console.log('Error', error)
}
} else {
console.log(error.message)
}
}
return (
<div>
{!success ?
<form onSubmit={handleSubmit}>
<fieldset className="FormGroup">
<div className="FormRow">
<CardElement options={CARD_OPTIONS} />
</div>
</fieldset>
<button>Pay</button>
</form >
:
<div>
<h2>You just bought a sweet saptula</h2>
</div>
}
</div>
)
}
I'd like to put a comment but I don't have the reputation to do it, so I'll submit an answer:
If you're trying to insert the elements provider following the documentation
the provider needs to be inserted this way:
import {Elements} from '#stripe/react-stripe-js';
you are importing this like
import {Element} from '#stripe/react-stripe-js';
it's possible that the element you're importing it's an interface or another object and not the provider you want