#StackBounty: #javascript #reactjs #typescript #react-native React Native check context value on click test case

Bounty: 200

I have following context

Home.tsx

export const ThemeContext = React.createContext(null)

const Home = () => {
  const { width } = Dimensions.get("window")
  const [theme, setTheme] = React.useState({
    active: 0,
    heightOfScrollView: 0,
    profileWidth: width * 0.2,
    scrolledByTouchingProfile: false
  })
  
  const horizontalScrollRef = React.useRef<ScrollView>()
  const verticalScrollRef = React.useRef<ScrollView>()

  return (
    <>
      <SafeAreaView style={styles.safeAreaContainer} />
      <Header title="Contacts" />
      <ThemeContext.Provider value={{ theme, setTheme }}>

In component A, I have a button which changes in the context

const onProfileTouched = (index: number) => {
  setTheme({ ...theme, active: index });
};

This leads to an image being active

const ImageCircle = ({ active, uri }: Props) => {
  return (
    <View
      style={
        active
          ? { ...styles.parentView, ...styles.active }
          : { ...styles.parentView }
      }>
      <Image source={uri} width={30} height={30} />
    </View>
  );
};

Now, I want to write a test case (I haven’t written a test case before) that confirms that the state has actually changed or perhaps an active border is added to the image

I added a testId to my button which I used to fire an event

it('changes active on profile clicked', () => {
  const { getByTestId } = render(<Home />);
  fireEvent.press(getByTestId('HScroll3.button'));
});

Now, I am unsure, how to grab the value of context or change in style so as I can confirm that indeed the component for which the button is pressed is active

I am using import {render, fireEvent} from '@testing-library/react-native' but open to change.


Get this bounty!!!

#StackBounty: #react-native #flexbox #scrollview #padding #react-native-flatlist React native Flatlist does not scroll inside the custo…

Bounty: 200

I have created one custom Animated bottom sheet. User can move the bottom sheet scroll up and down. Inside my bottom sheet, I have used flatList where I fetched the data and render the items as a card. Up-till now everything works as expected but I had an issue Flatlist scrolling. Inside the bottom sheet the Flat-list does not scroll. I have made hard coded height value 2000px, which is really practice and also FlatList’s contentContainerStyle added hard coded paddingBottom 2000(also another bad practice). I want to scroll the FlatList based on Flex-box. I don’t know how to fix this issue.

I share my code on expo-snacks

This is my all code

import React, { useState, useEffect } from "react";
import {
  StyleSheet,
  Text,
  View,
  Dimensions,
  useWindowDimensions,
  SafeAreaView,
  RefreshControl,
  Animated,
  Button,
  FlatList,
} from "react-native";

import MapView from "react-native-maps";
import styled from "styled-components";

import {
  PanGestureHandler,
  PanGestureHandlerGestureEvent,
  TouchableOpacity,
} from "react-native-gesture-handler";

const { width } = Dimensions.get("screen");

const initialRegion = {
  latitudeDelta: 15,
  longitudeDelta: 15,
  latitude: 60.1098678,
  longitude: 24.7385084,
};

const api =
  "http://open-api.myhelsinki.fi/v1/events/?distance_filter=60.1699%2C24.9384%2C10&language_filter=en&limit=50";

export default function App() {
  const { height } = useWindowDimensions();
  const [translateY] = useState(new Animated.Value(0));

  const [event, setEvent] = useState([]);
  const [loading, setLoading] = useState(false);

  // This is Fetch Dtata
  const fetchData = async () => {
    try {
      setLoading(true);
      const response = await fetch(api);
      const data = await response.json();

      setEvent(data.data);
      setLoading(false);
    } catch (error) {
      console.log("erro", error);
    }
  };
  useEffect(() => {
    fetchData();
  }, []);

  // Animation logic
  const bringUpActionSheet = () => {
    Animated.timing(translateY, {
      toValue: 0,
      duration: 500,
      useNativeDriver: true,
    }).start();
  };

  const closeDownBottomSheet = () => {
    Animated.timing(translateY, {
      toValue: 1,
      duration: 500,
      useNativeDriver: true,
    }).start();
  };

  const bottomSheetIntropolate = translateY.interpolate({
    inputRange: [0, 1],
    outputRange: [-height / 2.4 + 50, 0],
  });

  const animatedStyle = {
    transform: [
      {
        translateY: bottomSheetIntropolate,
      },
    ],
  };

  const gestureHandler = (e: PanGestureHandlerGestureEvent) => {
    if (e.nativeEvent.translationY > 0) {
      closeDownBottomSheet();
    } else if (e.nativeEvent.translationY < 0) {
      bringUpActionSheet();
    }
  };

  return (
    <>
      <MapView style={styles.mapStyle} initialRegion={initialRegion} />
      <PanGestureHandler onGestureEvent={gestureHandler}>
        <Animated.View
          style={[styles.container, { top: height * 0.7 }, animatedStyle]}
        >
          <SafeAreaView style={styles.wrapper}>
            <ContentConatiner>
              <Title>I am scroll sheet</Title>
              <HeroFlatList
                data={event}
                refreshControl={
                  <RefreshControl
                    enabled={true}
                    refreshing={loading}
                    onRefresh={fetchData}
                  />
                }
                keyExtractor={(_, index) => index.toString()}
                renderItem={({ item, index }) => {
                  const image = item?.description.images.map((img) => img.url);
                  const startDate = item?.event_dates?.starting_day;

                  return (
                    <EventContainer key={index}>
                      <EventImage
                        source={{
                          uri:
                            image[0] ||
                            "https://res.cloudinary.com/drewzxzgc/image/upload/v1631085536/zma1beozwbdc8zqwfhdu.jpg",
                        }}
                      />
                      <DescriptionContainer>
                        <Title ellipsizeMode="tail" numberOfLines={1}>
                          {item?.name?.en}
                        </Title>
                        <DescriptionText>
                          {item?.description?.intro ||
                            "No description available"}
                        </DescriptionText>
                        <DateText>{startDate}</DateText>
                      </DescriptionContainer>
                    </EventContainer>
                  );
                }}
              />
            </ContentConatiner>
          </SafeAreaView>
        </Animated.View>
      </PanGestureHandler>
    </>
  );
}

const styles = StyleSheet.create({
  container: {
    position: "absolute",
    top: 0,
    left: 0,
    right: 0,
    backgroundColor: "white",
    shadowColor: "black",
    shadowOffset: {
      height: -6,
      width: 0,
    },
    shadowOpacity: 0.1,
    shadowRadius: 5,
    borderTopEndRadius: 15,
    borderTopLeftRadius: 15,
  },
  mapStyle: {
    width: width,
    height: 800,
  },
});

const HeroFlatList = styled(FlatList).attrs({
  contentContainerStyle: {
    padding: 14,
    flexGrow: 1, // IT DOES NOT GROW
    paddingBottom: 2000, // BAD PRACTICE
  },
   height: 2000 /// BAD PRACTICE
})``; 


const ContentConatiner = styled.View`
  flex: 1;
  padding: 20px;
  background-color: #fff;
`;
const Title = styled.Text`
  font-size: 16px;
  font-weight: 700;
  margin-bottom: 5px;
`;

const DescriptionText = styled(Title)`
  font-size: 14px;
  opacity: 0.7;
`;

const DateText = styled(Title)`
  font-size: 14px;
  opacity: 0.8;
  color: #0099cc;
`;

const EventImage = styled.Image`
  width: 70px;
  height: 70px;
  border-radius: 70px;
  margin-right: 20px;
`;

const DescriptionContainer = styled.View`
  width: 200px;
`;

const EventContainer = styled(Animated.View)`
  flex-direction: row;
  padding: 20px;
  margin-bottom: 10px;
  border-radius: 20px;
  background-color: rgba(255, 255, 255, 0.8);
  shadow-color: #000;
  shadow-opacity: 0.3;
  shadow-radius: 20px;
  shadow-offset: 0 10px;
`;


Get this bounty!!!

#StackBounty: #react-native Vertically center image that's not affected by KeyboardAwareScrollView in React Native

Bounty: 50

Alright, so this has got me busy for quite a few hours already. I am trying to create a login screen where the main components are rendered on the bottom, with the logo in the remaining space. This is kind of what I would like to achieve:

desired result

To support my textinputs, I use KeyboardAwareScrollView, as it works better for me as opposed to KeyboardAvoidingView. My code currently looks like this (I plan on using a background image with a 50% color overlay rather than the red background, so the ImageBackground has to stay in place too):

  <ImageBackground
    source={require('./assets/img/background-clouds.png')}
    resizeMode="cover"
    style={styles.backgroundImage}>
    <View style={styles.backgroundOverlay} />
    <View style={styles.dummyView}>
      <Text>elloha</Text>
    </View>
    <Image
      source={require('./assets/img/logo.png')}
      style={styles.backgroundLogo}
      resizeMode="contain"
    />
    <KeyboardAwareScrollView
      keyboardShouldPersistTaps="always"
      keyboardOpeningTime={0}
      alwaysBounceHorizontal={false}
      alwaysBounceVertical={false}
      contentInsetAdjustmentBehavior="automatic"
      showsHorizontalScrollIndicator={false}
      showsVerticalScrollIndicator={false}
      automaticallyAdjustContentInsets={false}
      extraScrollHeight={30}
      enableOnAndroid>
      <StatusBar
        backgroundColor="transparent"
        barStyle="light-content"
        hidden={false}
        translucent
      />
      <TouchableWithoutFeedback
        onPress={Keyboard.dismiss}
        accessible={false}>
        <View style={styles.content}>
          <View style={styles.backgroundContainer}>
            <SafeAreaView style={{ flex: 0 }} />

            <View style={styles.loginContainer}>
              <View style={styles.loginScreen}>
                // textinputs and buttons go here
              </View>
              <SafeAreaView style={{ backgroundColor: 'white' }} />
            </View>
            <View
              style={{
                backgroundColor: 'white',
                height: Dimensions.get('window').height,
                position: 'absolute',
                width: Dimensions.get('window').width,
                top: Dimensions.get('window').height,
              }}
            />
          </View>
        </View>
      </TouchableWithoutFeedback>
    </KeyboardAwareScrollView>
  </ImageBackground>

Relevant styles:

const styles = StyleSheet.create({
  container: {
    backgroundColor: "white",
  },
  content: {
    flex: 1,
  },
  backgroundImage: {
    flex: 1,
    position: "absolute",
    top: 0,
    bottom: 0,
    left: 0,
    right: 0,
    width: Dimensions.get("window").width,
    height: Dimensions.get("window").height,
  },
  backgroundContainer: {
    justifyContent: "flex-end",
    flex: 1,
    width: Dimensions.get("window").width,
    height: Dimensions.get("window").height,
  },
  backgroundOverlay: {
    backgroundColor: "red",
    position: "absolute",
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
  },
  logoContainer: {
    top: "10%",
    width: "100%",
  },
  backgroundLogo: {
    alignSelf: "center",
    position: "absolute",
    width: 126,
    height: 96,
  },
  dummyView: {
    backgroundColor: "red",
    flex: 1,
  },
  loginContainer: {
    borderTopEndRadius: 30,
    borderTopStartRadius: 30,
    width: "100%",
    backgroundColor: "white",
    height: 500,
    alignItems: "center",
    paddingTop: Dimensions.get("window").width * 0.1,
  },
  loginScreen: {
    width: "80%",
    backgroundColor: "white",
  },
});

This yields the following result:

current result

I can get it done by adding top: 160 to the backgroundLogo style, but that’s a fixed value. I want it to be always in the center of the available space, but I’m unable to add a view between the background and the loginContainer, as all the logic for the keyboard and such is handled in between.

Is there a way to achieve what I want? Ideally, I should also be able to check the available height, and only show the logo if there is enough space (e.g. available height > 100, otherwise don’t show logo).

Important:
I want the logo to stay fixed, so if the keyboard is shown, the logo should not move up. The loginContainer should go "over" the logo


Get this bounty!!!

#StackBounty: #javascript #typescript #react-native #deep-linking #branch.io How to navigate from linking (deep linking with branch.io)…

Bounty: 50

I pretty much followed both react-navigation deep linking and branch.io react-native documentation, and either both are deprecated or just not completely helpful.

All I want is that whenever a deep link reads from the linking, navigate to a certain screen, I’m not looking to implement a listener on a specific screen, I want this on a root path, and is either the onReady (which for me didn’t work) or linking from navigator container

this is my code, very simple

const linking: LinkingOptions = {
  prefixes: ['agendameio://', 'https://agendame.io', 'https://agendameio.app.link', 'https://agendameio.app-alternative.link'],
  subscribe(listener) {
    const navigation = useNavigation();
    const onReceiveURL = ({ url }: { url: string }) => listener(url);
    Linking.addEventListener('url', onReceiveURL);
    branch.skipCachedEvents();
    branch.subscribe(async ({ error, params, uri }) => {
      if (error) {
        console.error('Error from Branch: ' + error);
        return;
      }
      if (params) {
        DataManager.DynamicURL = params['~id'] === "951933826563912687" ? params.id : undefined;
      }
      let url = params?.['+url'] || params?.['~referring_link']; // params !== undefined ? `agendameio://empresa/${params.id}` : 'agendameio://empresa';
      navigation.navigate(`DetalleEmpresa${params.id}`);
      listener(url);
    });
    return () => {
      Linking.removeEventListener('url', onReceiveURL);
      branch.logout();
    };
  },

I instantly get an error due to use navigation, but I really don’t know what else to use to navigate to inside the app

EDIT: this is the error in particular

Error

EDIT 2: I’ll add my navigation so it can help to understand my problem

function firstStack() {
  return (
    <homeStack.Navigator initialRouteName="EmpresasScreen">
      <homeStack.Screen
        options={({navigation}) => ({
          headerShown: false,
          headerTitle: () => (
            <>
              <View style={styles.viewHeader}>
                <Image 
                  resizeMode="contain" 
                  style={styles.imageLogo} 
                  source={Images.iconoToolbar} 
                />
              </View>
            </>
          ),
        })}
        name="EmpresasScreen"
        component={EmpresasScreen}
      />
      <detalleEmpresaStack.Screen
        options={{ headerShown: false }}
        name="DetalleEmpresaScreen"
        component={DetalleEmpresaScreen}
      />
      <agendamientoStack.Screen
        options={{ headerShown: false }}
        name="AgendamientoScreen"
        component={AgendamientoScreen}
      />
    </homeStack.Navigator>
  );
}

function secondStack() {
  return (
    <misCitasStack.Navigator>
      <misCitasStack.Screen
        options={({navigation}) => ({
          headerShown: false,
          headerTitle: () => (
            <>
              <View style={styles.viewHeader}>
                <Image 
                  resizeMode="contain" 
                  style={styles.imageLogo} 
                  source={Images.iconoToolbar} 
                />
              </View>
            </>
          ),
        })}
        name="MisCitasScreen"
        component={CitasScreen}
      />
      <detalleCitasStack.Screen
        options={({navigation}) => ({
          headerShown: false,
        })}
        name="DetalleCitaScreen"
        component={DetalleCitaScreen}
      />
    </misCitasStack.Navigator>
  );
}

function tabStack() {
  return (
    <tab.Navigator
      screenOptions={({route}) => ({
        tabBarIcon: ({focused}) => {
          let iconName;
          if (route.name === 'Home') {
            iconName = focused
              ? Images.casaActive
              : Images.casa
          } else if (route.name === 'Citas') {
            iconName = focused 
              ? Images.citasActive
              : Images.citas
          }
          return <Image source={iconName} />
        }
      })}
      tabBarOptions={{
        showLabel: false,
      }}>
      <tab.Screen name="Home" component={firstStack} />
      <tab.Screen name="Citas" component={secondStack} />
    </tab.Navigator>
  );
}

function menuStackNavigator() {
  useEffect(() => {
    VersionCheck.needUpdate({forceUpdate: true}).then(async res => {
      if (res.isNeeded) {
        alertNeedUpdate(res.storeUrl, false);
      }
    });
    if(Platform.OS === 'android') {
      NativeModules.SplashScreenModule.hide();
    }
  }, [])
  return (
    <NavigationContainer linking={linking}>
      <stack.Navigator headerMode="none">
        <stack.Screen name="Home" component={tabStack} />
        <stack.Screen name="Error" component={ErrorScreen} />
      </stack.Navigator>
    </NavigationContainer>
  );
};

const styles = StyleSheet.create({
  viewHeader: {
    alignItems: 'center',
    justifyContent: 'center',
  },
  imageLogo: {
    alignItems: 'center',
    justifyContent: 'center',
    marginTop: 6,
    marginBottom: 6
  }
});

export default menuStackNavigator;


Get this bounty!!!

#StackBounty: #react-native #redux #react-redux #expo #expo-notifications Handle incomming notification with expo-notifications

Bounty: 50

I have a problem regarding the following code sample:

Notifications.setNotificationHandler({//makes sure notification is displayed even when app is open, nothing else
    handleNotification: async (notification) => {
        //const value = await AsyncStorage.getItem('presetlanguage');
        //console.log("ASYNC STORAGE LANGUAGE FROM OUTSIDEEEE: ", value)
        //if(notification.request.content.body == "You received a new letter from a PigeonBuddy!"){
        //    console.log("hat geklappt")
        //}
        return{
            shouldShowAlert: true
        };
    }
});

const MainScreen = props => {
    const dispatch = useDispatch();
    var chosenLanguage = useSelector(state => state.myLanguage.myLanguage); ...........

The setNotificationHandler is responsible for handling incoming notifications and therefore I want to filter my incoming notifications. For example, depending on which screen I am on, I want to either display the notification or not display it. The problem however is, I have neither access to my navigation state nor to my redux states because this handling of the notifications happens outside the default screen main function which covers all variables and which also uses props through navigations. It is forbidden to call redux hooks there and also I have no access to my navigation state because I have no access to my props variable which I get through navigation.

How can I display my notifications then depending on which screen I am on? How are companies like Facebook doing it? If you’re on a chat screen you don’t get notifications but if you are outside a notification "New message received from …" is displayed.


Get this bounty!!!

#StackBounty: #reactjs #react-native #react-navigation #react-native-flatlist React native not re-rendering screen after state update

Bounty: 50

I am creating masonry list with react-native-seoul/masonry-list and fetching the data from API and updating the state afterwards. However, items are not rendered on screen but the console log of state variables shows data. Other think is that, when i save the file the data is render on screen.

Link to EXPO SNACK

In the example above, you can see that i have two screens

  • HotBytes
  • Favorite

Both screen uses same package to render masonry layout. However it is working in HotBytes Screen but not in Favorite Screen.

ISSUE

The items are not rendering after the data is fetched and state update in favorite screen

Link to EXPO SNACK


Get this bounty!!!

#StackBounty: #reactjs #firebase #react-native Can't authenticate to use Firebase API-s on Android with React-Native

Bounty: 50

I’m getting an error when authenticating with firebase. See the following error present in the Metro console window:

ERROR [Error: Your API key is invalid, please check you have copied it correctly.]

This happens upon running react-native run-android in my React-Native project. The app itself runs just fine, and I can use all functionality when running the web version of the project (thanks to react-native-web).

I configure firebase in a simple config file:

import firebase from 'firebase/app';
import '@firebase/auth';
import '@firebase/firestore';

const firebaseConfig = {
  apiKey: process.env.REACT_APP_API_KEY,
  authDomain: process.env.REACT_APP_AUTH_DOMAIN,
  projectId: process.env.REACT_APP_PROJECT_ID,
  storageBucket: process.env.REACT_APP_STORAGE_BUCKET,
  messagingSenderId: process.env.REACT_APP_MESSAGING_SENDER_ID,
  appId: process.env.REACT_APP_APP_ID,
  measurementId: process.env.REACT_APP_MEASUREMENT_ID,
};

if (!firebase.apps.length) {
  firebase.initializeApp(firebaseConfig);
}

export {firebase};

and import the exported firebase object in various places of my code. As you can see, the config is loaded from a .env file. If the values provided in it are for the web app, I can talk with the API-s just fine. However, if I provide config for Android, I keep getting the error mentioned before. I am completely clueless on why this happens.

I have tried various combinations of the config (including no config at all), but couldn’t quite succeed. I have google-services.json file in the android/app directory, and I believe I have all required dependencies and other configuration bits properly added to the android gradle files.


Get this bounty!!!

#StackBounty: #javascript #firebase #react-native #google-cloud-firestore Unable to bring Firebase database to application. Could not r…

Bounty: 50

I must say that I already did everything shown in the following questions, without being able to bring the data from the Database to my application:

@firebase/firestore: Firestore (5.0.4): Could not reach Cloud Firestore backend. Backend didn't respond within 10 seconds

React Native Could not reach Cloud Firestore backend

Ionic 5 emulator AVD Internet connection – error?

Firebase/Firestore not connected to internet

Firebase Firestore and Authentication Errors

Emulated firstore: Firestore (8.5.0): Could not reach Cloud Firestore backend

I have changed the version of Firebase, I have added code that works for others, I have looked for solutions on GitHub, etc.
I also looked for a solution on this site, but I can’t connect.

My React Native App makes use of Firebase.
I am trying to join the Firestore DataBase to my application, with no success.
The application so far has a list of products that are in the database, entered in it manually, from a Web application, which is perfectly connected to Firebase DataBase
Making Debugger, I check that the fix reaches me, thanks to a console.log, but it is empty, and in the Database I have several elements entered manually.

I show an image from the console.log

I always get the same Warning:

>  @ firebase / firestore: Firestore (7.19.0): Could not reach Cloud
> Firestore backend. Backend didn't respond within 10 seconds. This
> typically indicates that your device does not have a healthy Internet
> connection at the moment. The client will operate in offline mode
> until it is able to successfully connect to the backend

They are already 10 days testing solutions. I have changed the version of Firebase, I have added code that works for others,I have looked for answers on GitHub, etc. I also looked for a solution on this site, but I can’t connect.

I can’t continue with my application if I can’t get the data from the DataBase

I show images and code

import app from 'firebase/app'
import 'firebase/firestore'

import firebaseConfig from './config'

class Firebase {
    /*constructor() {
        if(!app.apps.length) {
            app.initializeApp(firebaseConfig)
        }

        this.db = app.firestore()
    }*/

    constructor() {
        if (!app.apps.length) {
            
            app.initializeApp(firebaseConfig)
            app.firestore().settings({ experimentalForceLongPolling: true })
            
        }

        this.db = app.firestore()
    }
}

const firebase = new Firebase()
export default firebase

FILE Menu.js

import React, { useContext, useEffect, Fragment } from 'react'
import { StyleSheet } from 'react-native'
import {
    Container,
    Separator,
    Content,
    List,
    ListItem,
    Thumbnail,
    Text,
    Body
} from 'native-base'
import globalStyles from '../styles/global'
import FirebaseContext from '../context/firebase/firebaseContext'

const Menu = () => {

    // Context de Firebase 
    const { menu, obtenerProductos } = useContext(FirebaseContext)

    useEffect(() => {
        obtenerProductos()

        console.log(menu)
    }, [])

    return (
        <Container style={globalStyles.contenedor}>
            <Content style={{ backgroundColor: '#FFF' }}>
                <List>
                    {menu.map(plato => {
                        const { imagen, nombre, descripcion, categoria, precio, id } = plato

                        return (
                            <Fragment key={id}>
                                <ListItem

                                >
                                    <Body>
                                        <Text>{nombre}</Text>
                                    </Body>
                                </ListItem>
                            </Fragment>
                        )
                    })}
                </List>
            </Content>
        </Container>
    )
}

const styles = StyleSheet.create({
    separador: {
        backgroundColor: '#000',
    },
    separadorTexto: {
        color: '#FFDA00',
        fontWeight: 'bold',
        textTransform: 'uppercase'
    }
})

export default Menu

FILE NuevaOrden.js

import React from 'react'
import { View, StyleSheet } from 'react-native'
import { Container, Button, Text, NativeBaseProvider } from 'native-base'
import globalStyles from '../styles/global'
import { useNavigation } from '@react-navigation/native'

const NuevaOrden = () => {

    const navigation = useNavigation()

    return (
        <Container style={globalStyles.contenedor}>
            <View style={[globalStyles.contenido, styles.contenido]}>
                <Button
                    style={globalStyles.boton}
                    rounded
                    block
                    onPress={() => navigation.navigate('Menu')}
                >
                    <Text style={globalStyles.botonTexto} >Crear Nueva Orden</Text>
                </Button>
            </View>
        </Container>
    )
}

const styles = StyleSheet.create({
    contenido: {
        flexDirection: 'column',
        justifyContent: 'center'
    }
})

export default NuevaOrden

FILE firebaseState.js

import React, { useReducer } from 'react'
import firebase from '../../firebase'
import FirebaseReducer from './firebaseReducer'
import FirebaseContext from './firebaseContext'

import { OBTENER_PRODUCTOS_EXITO } from '../../types'

const FirebaseState = props => {

  // Crear state inicial
  const initialState = {
    menu: []
  }

  // useReducer con dispatch  para ejecutar las funciones
  const [state, dispatch] = useReducer(FirebaseReducer, initialState)

  // Función que se ejecuta para traer los productos
  const obtenerProductos = () => {

    // consultar firebase
    //firebase.db.settings({ experimentalForceLongPolling: true })
    firebase.db
      .collection('productos')
      .where('existencia', '==', true) // traer solo los que esten en existencia
      .onSnapshot(manejarSnapshot)
      
    function manejarSnapshot(snapshot) {
      let platos = snapshot.docs.map(doc => {
        return {
          id: doc.id,
          ...doc.data()
        }
      })

      console.log(platos)

      // Tenemos resultados de la base de datos
      dispatch({
        type: OBTENER_PRODUCTOS_EXITO,
        payload: platos
      })    
    }
  }

  return (
    <FirebaseContext.Provider
      value={{
        menu: state.menu,
        firebase,
        obtenerProductos
      }}
    >
      {props.children}
    </FirebaseContext.Provider>
  )
}

export default FirebaseState

enter image description here

enter image description here

enter image description here

enter image description here


Get this bounty!!!

#StackBounty: #react-native #push-notification #react-navigation #react-native-onesignal RN OneSignal _open Event

Bounty: 100

OneSignal on notification open event fires after the home screen got launched then it navigates to the desired screen. I want to detect if the app was launched on pressing the notification prior the home screen get rendered so I can navigate to the Second screen directly and avoid unnecessarily calling of apis.

  • "react-native-onesignal": "^3.9.3"
  • "react-navigation": "^4.0.0"

code

   const _opened = openResult => {
      const { additionalData, body } = openResult.notification.payload;
     // how to navigate or set the initial screen depending on the payload
   }

    useEffect(() => {

        onesignal.init();
        onesignal.addEventListener('received', _received);
        onesignal.addEventListener('opened', _opened);
        SplashScreen.hide();

      return () => {
        // unsubscriber
        onesignal.removeEventListener('received', _received);
        onesignal.removeEventListener('opened', _opened);
      }
   }, []);

Debug

enter image description here


Get this bounty!!!