The problem:
I want to be able to debug GA4 without polluting my data. I can't seem to do that without removing my internal traffic filter, and then my presence on the app gets reported in Realtime reporting (and only Realtime reporting so far, but i suspect after 48 hours it will show everywhere in Reports).
First, is this expected behavior? Is Realtime reporting 'special'? Does it display dev traffic while other reports don't? If so, ignore the rest.
What I've tried:
I used google chrome with the GA debug extension from here: ga debugger ext to review my website (on localhost).
When my Internal Traffic filter is deactivated and my Developer Traffic filter is activated, Realtime reports show my presence on my app (boo). But I do see data in the debug view (yay).
When both are activated no data is shown in the Realtime reports area (yay), but also no data is shown in the debug view (boo).
Some Code:
import ReactGA from "react-ga4";
function App() {
useEffect(() => {
ReactGA.initialize("G-blablabla");
ReactGA.send("pageview");
},
[]
)
let location = useLocation();
useEffect(() => {
ReactGA.send({ hitType: "pageview", page: location });
}, [location]);
const GenerateAppRoutes = () => {
return (
<>
<Route path="/" element={
<Landing/>
}
/>
<Route path="/blog/design" element={
<BlogPillar
imgSrc={sampleImg}
topicTitle='Design'
articles={
[
{'link': '/blog/design/materials', 'title': 'Materials'},
{'link': '/blog/design/fasteners', 'title': 'Screws'},
]
}
imgAlt=""
/>
}/>
</>
)
}
const AppRoutes = GenerateAppRoutes();
const appRouteObjects = createRoutesFromChildren(AppRoutes);
const GeneratedRoutes = useRoutes(appRouteObjects);
return (
<>
<NavBarComponent/>
{GeneratedRoutes}
</>
)
}
export default App;
Related
after searching half a day I still not able to getItem from local storage.
the idea is to save some data to local storage and based on that I want to route a user in the Layout component. I am able to save to local storage and delete but not able to get data from it. I get error 'local storage not defined' or 'destroy is not a function'
I have 3 components save, delete and get. save and delete I execute after a client side api call, the get function I need to be working in the Layout as it is the top level for all routes.
I Need a bit help to the right direction please.
---Upadte
I found something that works
export const IsAuth = ()=>{
const [auth, setAuth] = useState();
useEffect(()=>{
if(typeof windows === undefined) return;
const item = localStorage.getItem('ltu');
setAuth(!!item);
},[]);
return auth;
}
now my problem is I have not much understanding of nextjs. I used the Layout to create a theme template, I basically have only 3 pages that can be visited if not logged in and the rest one needs to be logged in. I get so many examples but it seems like I need to verify auth on every single page instead of being able to do this on root/layout level.
all examples I get are without the use of Layout and I am totally stuck.
I want a simple login system just with jwt and check if thats there to show pages.
I could not get the localStorage.getItem() to work in the layout template.
My solution while maybe not perfect is.
in the _app.js I create useState() and pass those along to the menu trough the Layout, in in the menu useEffect() with 'use client' in the useEffect I set the state I need global.
_app.js
export default function App({ Component, pageProps }){
const [isAuth, setAuth] = useState()
const [user, setUser] = useState()
return (
<Layout setAuth={setAuth} isAuth={isAuth} user={user} setUser={setUser}>
<Component user={user} setUser={setUser} isAuth={isAuth} {...pageProps} />
</Layout>
)
}
Layout.js
export default function Layout({ children, setAuth, isAuth, user, setUser }) {
return (
<>
<Headd />
<SideMenu setAuth={setAuth} isAuth={isAuth} user={user} setUser={setUser}/>
<main>
<div className="menu-spacer"></div>
<content>
{children}
</content>
</main>
</>
)
}
menu.js
'use client';
const SideMenu = ({setAuth, isAuth, user, setUser}) => {
useEffect(()=>{
if(typeof windows === undefined) return;
const item = localStorage.getItem('ltu');
setAuth(!!item);
if(item) setUser(JSON.parse(localStorage.getItem('Ud')))
}, [router, router.isReady])
}
Now I can use the {isAuth, user,} on any page and component.
I am pretty sure this is not the right solution, but I could not find any other working solution and no one here yet posted a answer.
Attempting to let Firebase persist authentication within the app.js of React Native by doing the following:
There is a sign in page that envokes auth() sign in via Firebase, which works fine, and redirects to the home page via navigation.replace("Home"); however, once the app is closed and relaunched on the emulator, it redirects back to sign in.
This is seemingly what the App.js looks like, I assume that the AuthStateChanged would be prevalent as depicted below, however, user is not accessed in App.js as it is established in SignIn.js, when the Firebase credentials are sent, but I assume it would be similar to this layout?
const App = () => {
var initialRoute = null
React.useEffect(() => {
const unsubscribe = auth().onAuthStateChanged(user => {
if(user) {
initialRoute = "Home"
}
else {
initialRoute = "SignIn"
}
})
return unsubscribe
}, []);
return (
<NavigationContainer>
<Stack.Navigator
screenOptions={{
headerShown: false,
}}
initialRouteName={initialRoute}
>
The reason it needs to affect the initial route, and not just redirect anyone who reopens to the home page, is because after registration, there are extra steps included that adjust the database, such as location mapping and etc., therefore, the redirection has to occur within the initial route.
Thanks for your assistance.
This is not how you build a navigation flow with react-navigation. But that's no problem since theres a guide here on the official react-navigation side on how to do that: https://reactnavigation.org/docs/auth-flow/
Fixed by setting two different returns within App.js, one for if the user is authenticated with Firebase that sets the initialRoute to "Home", and one for else that sets it to "SignUp", seems to work fine.
Background
I'm trying to build an app which shows a number of stores, in the home screen which is a function component (mind this as I need to use hooks) I have a scroll view which shows different stores.
What I need
When the user presses on one of the stores it should redirect it to a screen which has the information of that specific store. I have built the "store detail" screen but with static info, I want to replace all of that information with data stored in a firestore collection.
Question
How would one go about retrieving data from a Firestore collection in react native, then assigning the data from each document to a separate Touchable Opacity (I know about passing params with react navigation, I just don't know which param to pass when working with Firestore), and then displaying that data in the store detail screen?
Sample code for context
App.js
<NavigationContainer>
<Stack.Navigator initialRouteName={user ? 'Home' : 'Login'}
screenOptions={{cardStyle: { backgroundColor: '#FFFFFF' }}}>
<Stack.Screen name="Home"options={{headerShown: false}}>
{props => <HomeScreen {...props} extraData={user} />}
</Stack.Screen>
<Stack.Screen name="Login" component={LoginScreen} options={{headerShown: false}}/>
<Stack.Screen name="Registration" component={RegistrationScreen} options={{headerShown: false}}/>
<Stack.Screen name="storeDetail" options={{title: ''}}>
{props => <storeDetail {...props} extraData={} />}
</Stack.Screen>
</Stack.Navigator>
</NavigationContainer>
In this file you'll see that I've already called some data (Login and Register pass userData to the Home Screen), however in order to implement that method I depended on the response from the authentication method I was using. I imagine although, I will probably need to pass something as extraData, I understand what I should do, I just don't know how to fill the blank spaces.
Thanks a lot in advance!
First, install the Firebase SDK in your app, so you can make queries to your backend.
I don't know if your sample App.js represents the current state of progress on your app, but I'm going to assume that:
you already have your storeDetail screen built
you know the store's id before navigating to the screen (eg in the HomeScreen)
you pass the storeId as a navigation param when navigating to storeDetail
So in storeSetails screen, you can query Firestore when receiving storeId, and save the result to a state variable on success:
const StoreDetailsScreen = ({ route }) => { // route is passed as a prop by React Navigation
const { storeId } = route.params
const [store, setStore] = useState()
const [loading, setLoading] = useState(true) // show a loading spinner instead of store data until it's available
useEffect(() => {
const fetchQuery = async () => {
const storeData = await firestore()
.collection('stores')
.doc(storeId)
.get() // this queries the database
if (storeData) {
setStore(storeData) // save the data to store state
setLoading(false) // set loading to false
} else {
// something went wrong, show an error message or something
}
}
fetchQuery()
}, [storeId])
if (loading) {
return (
<ActivityIndicator/>
)
}
return (
// ... store details
)
}
Then you can use the data in store to render stuff in your screen
<Text>{store.name}</Text>
<Text>{store.email}</Text>
// ...
More info about how to use Firestore in RN: https://rnfirebase.io/firestore/usage
I'm currently working on a administration for a site, and I was wondering what's the best way to check if user is logged in and render the routes to give access to it.
From meteor's documentation I can see: https://docs.meteor.com/api/accounts.html#Meteor-userId
Which is a quite a convenient way, but I'm wondering if it is secure enough to render administration routes on the client side.
Here's an example to what I would like to do :
const checkFunction=()=>{
if(Meteor.isClient){
return Meteor.userId();
}
}
const PrivateRoute = ({ layout, component, ...rest }) => (
<Route
{...rest}
render={props =>
checkFunction() ? (
React.createElement( layout, props, React.createElement(component, props))
) : (
<Redirect
to={{
pathname: "/login",
state: { from: props.location }
}}
/>
)
}
/>
);
Eventhough I make sure that every modifications on the database are also checked server side, I don't want to give an insecure access to my administration.
I have a router that looks something like this
<Router>
<Switch>
<Route path="abc.do" render={() => <SetupAppInitialLoad pageKey="abc" />} />
<Route path="xyz.do" render={() => <SetupAppInitialLoad pageKey="xyz" />} />
</Switch>
</Router>
I have many Route like these inside <Switch>. I am using redux to handle state and dispatching async actions from some components when user clicks on a button/link.
export const asyncExampleAction = () => {
return (dispatch, getState) => {
//logic to send inputs to server comes here
.then(checkStatus)
.then(parseJSON)
.then( (data) => {
if (success case) {
history.push(`something.do?phase=something`);
} else {
//handle error logic
}
})
.catch( (error) => {
console.log(error);
});
}
}
Now, the problem I am facing is, even though history.push updates the url and navigates me to 'something.do?phase=something', but I don't see Route's history.location getting updated. Because of this (I think), when I click on some link on the page 'something.do?phase=something', only url of the page changes, but navigation to that new page doesn't happen.
I checked Programmatically navigate using react router V4 and Programmatically navigate using react router, but still not getting anywhere. Please help.
That happens because react-router does not directly depend on window.history, but instead uses this history project, which wraps window.history and provides react-router with the possibility to listen to location updates and react on them.
You have to options to update navigate from your actions:
Use react-router-redux library.
Or pass history prop from your Component to your actions and use it to navigate inside of them.
Second option is the one officialy recommended by react-router doc:
Rather than dispatching actions to navigate you can pass the history object provided to route components to your actions and navigate with it there.