Populate Picker items with data from Firebase Realtime Database in React Native

280 Views Asked by At

I am trying to use Firebase Realtime Database to populate the items in picker (@react-native-picker/picker) and have failed repeatedly.
I am also attaching a minimal reproducible example below.
Through the onPress event, console.log() is printing the correct array, but I am unable to use it to generate an array for Picker to use.
I would greatly appreciate any help or resources you provide.

import React, { useState } from 'react';
import { StyleSheet, View, Text, Pressable } from 'react-native';
import { Picker } from '@react-native-picker/picker';
import Firebase from './config/firebase';

const Test = () => {
  const [selectedAnimal, setSelectedAnimal] = useState();

  var generateList = (path) => {
    var Listener = Firebase.database().ref(path);
    return Listener.once('value');
  };

  let pickerGenerator = (dblist) => dblist.map(i => {
    return <Picker.Item key={i} label={i.toString()} value={i} />
  });
  
  return (
    <View style={styles.container}>
      <View style={styles.InputContainer}>
      <Picker
        selectedValue={selectedAnimal}
        style={styles.UserInput}
        onValueChange={(itemValue, itemIndex) =>
          setSelectedAnimal(itemValue)
      }>
        {/* {generateList('/Static/Animals').then(data => {
          pickerGenerator(data.val());
        })} */}
      </Picker>
      </View>
      <Pressable
        style={styles.button}
        android_ripple={{ color: 'white' }}
        onPress={() => {
        generateList('/Static/Animals').then(data => {
          console.log(data.val());
        })
      }}>
      <Text style={styles.buttoncontent}>Test</Text>
      </Pressable>
    </View>
  )
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
    marginHorizontal: 8,
  },
  InputContainer: {
    alignSelf: 'stretch',
    marginBottom: 20,
    borderWidth: 1,
    borderStyle: 'solid',
    borderColor: 'darkviolet',
    borderRadius: 4,
  },
  UserInput: {
    fontSize: 16,
    height: 42,
    paddingHorizontal: 8,
  },
  button: {
    alignItems: 'center',
    justifyContent: 'center',
    paddingVertical: 12,
    paddingHorizontal: 32,
    marginVertical: 5,
    borderRadius: 4,
    elevation: 5,
    backgroundColor: 'cornflowerblue',
  },
  buttoncontent: {
    textAlign: 'center',
    fontSize: 16,
    lineHeight: 24,
    fontWeight: 'bold',
    color: 'white',
  },
});

export default Test;
1

There are 1 best solutions below

0
On BEST ANSWER

I got it working through trial and error.

import React, { useState } from 'react';
import { StyleSheet, View, Text, Pressable } from 'react-native';
import { Picker } from '@react-native-picker/picker';
import Firebase from './config/firebase';

var generated = [];

const Test = () => {
  const [selectedAnimal, setSelectedAnimal] = useState();

  var generateList = (path) => {
    var Listener = Firebase.database().ref(path);
    Listener.once('value', (snapshot) => {
      const data = snapshot.val();
      generated = data;
    });
    return generated;
  };

  let pickerGenerator = (dblist) => dblist.map(i => {
    return <Picker.Item key={i} label={i.toString()} value={i} />
  });
  
  return (
    <View style={styles.container}>
      <View style={styles.InputContainer}>
      <Picker
        selectedValue={selectedAnimal}
        style={styles.UserInput}
        onValueChange={(itemValue, itemIndex) =>
          setSelectedAnimal(itemValue)
      }>
        {pickerGenerator(generateList('/Static/Animals'))}
      </Picker>
      </View>
      <Pressable
        style={styles.button}
        android_ripple={{ color: 'white' }}
        onPress={() => {
          console.log(generateList('/Static/Animals'));
      }}>
      <Text style={styles.buttoncontent}>Test</Text>
      </Pressable>
    </View>
  )
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
    marginHorizontal: 8,
  },
  InputContainer: {
    alignSelf: 'stretch',
    marginBottom: 20,
    borderWidth: 1,
    borderStyle: 'solid',
    borderColor: 'darkviolet',
    borderRadius: 4,
  },
  UserInput: {
    fontSize: 16,
    height: 42,
    paddingHorizontal: 8,
  },
  button: {
    alignItems: 'center',
    justifyContent: 'center',
    paddingVertical: 12,
    paddingHorizontal: 32,
    marginVertical: 5,
    borderRadius: 4,
    elevation: 5,
    backgroundColor: 'cornflowerblue',
  },
  buttoncontent: {
    textAlign: 'center',
    fontSize: 16,
    lineHeight: 24,
    fontWeight: 'bold',
    color: 'white',
  },
});

export default Test;