Firebase + React native file upload error 400 - firebase

Hello I'm using firebase for the first time, I want to upload a file (video or image) to firebase but I keep getting error 400
I'm using react native
import { storage_bucket } from '../firebase';
import { ref,uploadBytesResumable } from "firebase/storage";
import { View, Text } from 'react-native'
import React from 'react'
export default function test() {
const uploadVideo = (e) => {
let file = e.target.files[0];
let fileRef = ref(storage_bucket,file.name);
const uploadTask = uploadBytesResumable(fileRef,file);
uploadTask.on('state_changed',(snapshot) => {
const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
console.log('uplaod is' + progress + '% done');
})
}
return (
<View>
<input type="file" onChange={uploadVideo}></input>
</View>
)
}

Related

nextjs 13 generateStaticParams used with next/header causes unhandled runtime error in dev mode

I am working on a new project, and recently used nextjs13 for my frontend application.
When using the function generateStaticParams with the next/header library function headers(),
I get an error in dev mode.
Error occured during dev mode
But when the frontend is on using next build / next start, the error does not appear.
The main reason I am using the next/header library is due to next-auth, to gain access to cookies.
generateStaticParams is in the app/detail/[questionId]/page.tsx file
next/headers is in app/layout.tsx file
app/page.tsx
import React from "react";
import QuestionCard from "../components/Card/QuestionCard";
import Carousel from "../components/Carousel/Carousel";
import HomeNavBar from "../components/HomeNavBar/HomeNavBar";
import { ICarousel } from "../types/carousel";
import TabNavigator from "../components/TabNavigator/TabNavigator";
const getGoogleSession = async () => {};
const getQuestionList = async () => {
const response = await fetch(`https://pioneroroom.com/questionlist`);
const data = await response.json();
return data;
};
const page = async ({ Question }: any) => {
// const imageArr = await getCarouselImages();
const data = await getQuestionList();
return (
<div className="main">
<HomeNavBar />
{/* <Carousel carousel={imageArr} /> */}
<div className="contentbody">
{data.data.map((e: any) => {
return <QuestionCard key={e.questionId} question={e} />;
})}
</div>
<TabNavigator activeLink={""} />
</div>
);
};
export default page;
app/layout.tsx
import { Roboto, Noto_Sans_KR } from '#next/font/google';
import NavBar from '../components/HomeNavBar/HomeNavBar';
import '../styles/globals.css';
import SessionContainer from '../components/Providers/SessionProvider';
import '../styles/globals.css';
import { unstable_getServerSession } from 'next-auth';
import { getSession } from '../utils/helper/session';
import { cookies, headers } from 'next/headers';
import HomeNavBar from '../components/HomeNavBar/HomeNavBar';
import TabNavigator from '../components/TabNavigator/TabNavigator';
const noto = Noto_Sans_KR({
weight: '400',
fallback: ['Roboto'],
subsets: ['latin'],
});
const RootLayout = async ({ children }: any) => {
const { segment } = children.props.childProp;
const session = await getSession(headers().get('cookie') ?? '');
const nextCookies = cookies();
return (
<html className={noto.className}>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>asdf</title>
</head>
<body>
<SessionContainer session={session}>{children}</SessionContainer>
</body>
</html>
);
};
export default RootLayout;
app/detail/[questionId]/page.tsx
import { headers } from 'next/headers';
import React, { use } from 'react';
import { getSession } from '../../../utils/helper/session';
const fetchPost = async (id: any) => {
const res = await fetch(`https://pioneroroom.com/questionlist/${id}`);
return await res.json().then((res) => res.data);
};
const DetailIdPage = async ({ params }: any) => {
console.log('params.questionId', params.questionId);
const post = await fetchPost(params.questionId);
return (
<div>
<p>{JSON.stringify(post)}</p>
</div>
);
};
// BUG: generateStaticParams 함수가 현재 dev 모드에서 동작하지 않음.
// dynamic headers( next/headers )의 cookie등을 불러올 때 오류를 일으키고,
// dev mode에서 이 함수와 결합하여 사용하면 dynamic server usage: headers error 발생함.
/*
export async function generateStaticParams() {
const res = await fetch('https://pioneroroom.com/questionlist');
const data = await res.json();
const arr = data.data.map((e: any) => {
console.log('map', e.questionId);
return {
questionId: String(e.questionId),
};
});
return arr;
}
*/
export default DetailIdPage;
Erasing either both of the code (generateStaticParams or next/header) solves the problem. No errors occuring in dev mode.

Next.js: How to use useState and AuthContext without invalidating SSG html

I have an AuthContext to manage the authentication in my Next.js app. The _app.js file looks like this:
import '../styles/global.css'
import 'tailwindcss/tailwind.css'
import { AuthProvider } from '../components/AuthContext'
function MyApp({ Component, pageProps }) {
return (
<>
<AuthProvider>
<Component {...pageProps} />
</AuthProvider>
</>
)
}
export default MyApp
And the AuthContext file is something like this:
import React, { useContext, useState, useEffect } from "react"
import { auth, db } from "./Firebase";
import { doc, getDoc } from "firebase/firestore";
const AuthContext = React.createContext()
export function AuthProvider({ children }) {
const [currentUser, setCurrentUser] = useState([])
const [loading, setLoading] = useState(true)
const [userData, setUserData] = useState({})
const [companyData, setCompanyData] = useState({})
useEffect(() => {
const unsubscribe =
auth.onAuthStateChanged(user => {
setCurrentUser(user)
setLoading(false)
})
return unsubscribe
}, [])
useEffect(() => {
const fetchData = async () => {
const qu = doc(db, "users", currentUser.uid)
const datau = await getDoc(qu)
setUserData(datau.data());
const qc = doc(db, "companies", currentUser.uid)
const datac = await getDoc(qc)
setCompanyData(datac.data());
}
currentUser?.uid && fetchData()
}, [currentUser])
const value = {
currentUser,
userData,
companyData
}
return (
<AuthContext.Provider value={value}>
{!loading && children}
</AuthContext.Provider>
)
}
export function useAuth() {
return useContext(AuthContext)
}
Then I have a dynamic page [id].js that is something like this:
import { useAuth } from '../../components/AuthContext';
import Head from 'next/head';
export async function getStaticProps(context) {
// fetch and return data
}
export async function getStaticPaths() {
// fetch paths
return { paths, fallback: 'blocking' }
}
export default function Job(props) {
const { userData, currentUser } = useAuth();
const data = props.data;
return (
<>
<Head>
{data.title} | SiteName
</Head>
<h1>data.title</h1>
{currentUser ? userData.name : null}
</>
)
}
Problem: The website works perfectly, BUT when I check the page [id].js source code, Next.js doesn't build the HTML structure with head and body optimized for SEO (which is the main reason why I'm migrating to Next.js).
If I remove the "!loading &&" (see below) in the AuthContext file, the Next's SSG HTML generation works BUT the whole app starts to give me errors everywhere.
<AuthContext.Provider value={value}>
{children}
</AuthContext.Provider>
What exactly is the problem? And any idea on how to solve it?

How to add firebase screen tracking analytics with React Native React Navigation when using createStackNavigator?

I have a React Native app and am using React Navigation. I am now trying to add screen tracking analytics with firebase.
I am following this documentation, which has this sample code:
import analytics from '#react-native-firebase/analytics';
import { NavigationContainer } from '#react-navigation/native';
<NavigationContainer
ref={navigationRef}
onStateChange={state => {
const previousRouteName = routeNameRef.current;
const currentRouteName = getActiveRouteName(state);
if (previousRouteName !== currentRouteName) {
analytics().setCurrentScreen(currentRouteName, currentRouteName);
}
In my code, however, I am creating my base NavigationContainer with a function like so:
export default createStackNavigator(
{
Home: MainTabNavigator,
SignIn: SignInNavigator,
},
{
transitionConfig: dynamicModalTransition,
headerMode: 'none',
initialRouteName: 'Home',
},
);
What is the best way to integrate the code from the example?
The problem is because you are on react-navigation v4.x.x, but the example you have is for v5.x.x.
In v4, event listeners can be added on AppContainer.
The example below is for v4.
import React from 'react';
import { createAppContainer, createStackNavigator } from 'react-navigation';
function getActiveRouteName(navigationState) {
if (!navigationState) {
return null;
}
const route = navigationState.routes[navigationState.index];
if (route.routes) {
return getActiveRouteName(route);
}
return route.routeName;
}
const nav = createStackNavigator({...});
const AppContainer = createAppContainer(nav);
export default () => {
return <AppContainer
onNavigationStateChange={(prevState, currentState, action) => {
const currentRouteName = getActiveRouteName(currentState);
const previousRouteName = getActiveRouteName(prevState);
if (previousRouteName !== currentRouteName) {
analytics().setCurrentScreen(currentRouteName, currentRouteName);
}
}}
/>
}
I'm using NavigationContainer and createStackNavigator, too and this is how I did it, like in the example for screen tracking at reactnavigation.org
import * as Analytics from 'expo-firebase-analytics';
import { useRef } from 'react';
import { NavigationContainer } from '#react-navigation/native';
export default () => {
const navigationRef = useRef();
const routeNameRef = useRef();
return (
<NavigationContainer
ref={navigationRef}
onReady={() =>
(routeNameRef.current = navigationRef.current.getCurrentRoute().name)
}
onStateChange={async () => {
const previousRouteName = routeNameRef.current;
const currentRouteName = navigationRef.current.getCurrentRoute().name;
if (previousRouteName !== currentRouteName) {
// The line below uses the expo-firebase-analytics tracker
// https://docs.expo.io/versions/latest/sdk/firebase-analytics/
// Change this line to use another Mobile analytics SDK
await analytics().logScreenView({
screen_name: currentRouteName,
screen_class: currentRouteName
});
}
// Save the current route name for later comparison
routeNameRef.current = currentRouteName;
}}
>
{/* ... */}
</NavigationContainer>
);
};

Trying to subscribe to a collectionusing react-meteor-hooks but loading is always true

Trying to implement 'react-meteor-hooks, but 'loading' variable is always true:
import React from 'react';
import { useSubscription, useMongoFetch } from 'react-meteor-hooks';
import { Comments } from '../../../../collections/comments';
export const GiveComments = (props) => {
const loading = useSubscription('getComments');
if (loading) {
console.log('loading... ');
} else {
const allComments = useMongoFetch(Comments.find({}));
console.log('loaded: ', allComments);
}
return (null);
};
Publishing:
Meteor.publish('getComments', function() {
return Comments.find({});
});
These hooks looks amazing, but can't get it to work. Why 'loading' does not stop?

"Cannot read property of undefined" being thrown by react-apollo used with React-NextJS

My NextJS project has been giving me grief over Graph QL these days. I've been trying to implement an Apollo client solution to retrieve data from a remote GraphQL server into a custom component. But no matter which solution I try, I always end up with this error. Here's my current react-apollo implementation:
// /lib/with-apollo-client.js
import React from "react";
import Head from "next/head";
import { getDataFromTree } from "react-apollo";
import initApollo from "./init-apollo";
export default App => {
return class WithData extends React.Component {
static displayName = `WithData(${App.displayName})`;
static async getInitialProps(ctx) {
const { Component, router } = ctx;
const apollo = initApollo({});
ctx.ctx.apolloClient = apollo;
let appProps = {};
if (App.getInitialProps) {
appProps = await App.getInitialProps(ctx);
}
// Run all GraphQL queries in the component tree
// and extract the resulting data
if (!process.browser) {
try {
// Run all GraphQL queries
await getDataFromTree(
<App
{...appProps}
Component={Component}
router={router}
apolloClient={apollo}
/>
);
} catch (error) {
console.error("Error while running `getDataFromTree`", error);
}
// getDataFromTree does not call componentWillUnmount
// head side effect therefore need to be cleared manually
Head.rewind();
}
// Extract query data from the Apollo store
const apolloState = apollo.cache.extract();
return {
...appProps,
apolloState
};
}
constructor(props) {
super(props);
this.apolloClient = initApollo(props.apolloState);
}
render() {
return <App {...this.props} apolloClient={this.apolloClient} />;
}
};
};
// /lib/init-apollo.js
import { ApolloClient, InMemoryCache, HttpLink } from 'apollo-boost'
import fetch from 'isomorphic-unfetch'
let apolloClient = null
// Polyfill fetch() on the server (used by apollo-client)
if (!process.browser) {
global.fetch = fetch
}
function create (initialState) {
// Check out https://github.com/zeit/next.js/pull/4611 if you want to use the AWSAppSyncClient
return new ApolloClient({
connectToDevTools: process.browser,
ssrMode: !process.browser, // Disables forceFetch on the server (so queries are only run once)
link: new HttpLink({
uri: 'https://api.graph.cool/simple/v1/cixmkt2ul01q00122mksg82pn', // Server URL (must be absolute)
credentials: 'same-origin' // Additional fetch() options like `credentials` or `headers`
}),
cache: new InMemoryCache().restore(initialState || {})
})
}
export default function initApollo (initialState) {
// Make sure to create a new client for every server-side request so that data
// isn't shared between connections (which would be bad)
if (!process.browser) {
return create(initialState)
}
// Reuse client on the client-side
if (!apolloClient) {
apolloClient = create(initialState)
}
return apolloClient
}
The component I'm retrieving data into looks like this:
// /components/PostsList2.jsx
import { Query } from 'react-apollo'
import gql from 'graphql-tag'
export const allUsersQuery = gql`
query allUsers($first: Int!, $skip: Int!) {
allUsers(orderBy: createdAt_DESC, first: $first, skip: $skip) {
id
firstName
createdAt
}
_allUsersMeta {
count
}
}
`
export const allUsersQueryVars = {
skip: 0,
first: 10
}
export default function PostsList2 () {
return (
<Query query={allUsersQuery} variables={allUsersQueryVars}>
{({ loading, error, data: { allUsers, _allUsersMeta }, fetchMore }) => {
if (error) return <aside>Error loading users!</aside>
if (loading) return <div>Loading</div>
const areMorePosts = allUsers.length < _allUsersMeta.count
return (
<section>
<ul>
{allUsers.map((user, index) => (
<li key={user.id}>
<div>
<span>{index + 1}. </span>
<div>{user.firstName}</div>
</div>
</li>
))}
</ul>
{areMorePosts ? (
<button onClick={() => loadMorePosts(allUsers, fetchMore)}>
{' '}
{loading ? 'Loading...' : 'Show More'}{' '}
</button>
) : (
''
)}
</section>
)
}}
</Query>
)
}
function loadMorePosts (allUsers, fetchMore) {
fetchMore({
variables: {
skip: allUsers.length
},
updateQuery: (previousResult, { fetchMoreResult }) => {
if (!fetchMoreResult) {
return previousResult
}
return Object.assign({}, previousResult, {
// Append the new users results to the old one
allUsers: [...previousResult.allUsers, ...fetchMoreResult.allUsers]
})
}
})
}
Since this is a NextJS project, there's also an _app.jsx that I've wrapped in a special provider component:
// /pages._app.jsx
/* eslint-disable max-len */
import '../static/styles/fonts.scss';
import '../static/styles/style.scss';
import '../static/styles/some.css';
import CssBaseline from '#material-ui/core/CssBaseline';
import { ThemeProvider } from '#material-ui/styles';
import jwt from 'jsonwebtoken';
import withRedux from 'next-redux-wrapper';
import App, {
Container,
} from 'next/app';
import Head from 'next/head';
import React from 'react';
import { Provider } from 'react-redux';
import makeStore from '../reducers';
import mainTheme from '../themes/main-theme';
import getSessIDFromCookies from '../utils/get-sessid-from-cookies';
import getLanguageFromCookies from '../utils/get-language-from-cookies';
import getUserTokenFromCookies from '../utils/get-user-token-from-cookies';
import removeFbHash from '../utils/remove-fb-hash';
import withApolloClient from '../lib/with-apollo-client'
import { ApolloProvider } from 'react-apollo'
class MyApp extends App {
static async getInitialProps({ Component, ctx }) {
let userToken;
let sessID;
let language;
if (ctx.isServer) {
ctx.store.dispatch({ type: 'UPDATEIP', payload: ctx.req.headers['x-real-ip'] });
userToken = getUserTokenFromCookies(ctx.req);
sessID = getSessIDFromCookies(ctx.req);
language = getLanguageFromCookies(ctx.req);
const dictionary = require(`../dictionaries/${language}`);
ctx.store.dispatch({ type: 'SETLANGUAGE', payload: dictionary });
if(ctx.res) {
if(ctx.res.locals) {
if(!ctx.res.locals.authenticated) {
userToken = null;
sessID = null;
}
}
}
if (userToken && sessID) { // TBD: validate integrity of sessID
const userInfo = jwt.verify(userToken, process.env.JWT_SECRET);
ctx.store.dispatch({ type: 'ADDUSERINFO', payload: userInfo });
}
ctx.store.dispatch({ type: 'ADDSESSION', payload: sessID }); // component will be able to read from store's state when rendered
}
const pageProps = Component.getInitialProps ? await Component.getInitialProps(ctx) : {};
return { pageProps };
}
componentDidMount() {
// Remove the server-side injected CSS.
const jssStyles = document.querySelector('#jss-server-side');
if (jssStyles) {
jssStyles.parentNode.removeChild(jssStyles);
}
// Register serviceWorker
if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/serviceWorker.js'); }
// Handle FB's ugly redirect URL hash
removeFbHash(window, document);
}
render() {
const { Component, pageProps, store, apolloClient } = this.props;
return (
<Container>
<Head>
// redacted for brevity
</Head>
<ThemeProvider theme={mainTheme}>
{/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
<CssBaseline />
<ApolloProvider client={apolloClient}>
<Provider store={store}>
<Component {...pageProps} />
</Provider>
</ApolloProvider>
</ThemeProvider>
</Container>
);
}
}
export default withApolloClient(withRedux(makeStore)(MyApp));
So with this setup, when I compile and run my app, it throws the following:
TypeError: Cannot read property 'allUsers' of undefined
I'm really lost! The repo is up at https://github.com/amitschandillia/proost/tree/master/web.

Resources