Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Returning null when using iPhone device #6

Open
nonoumasy opened this issue Jul 11, 2021 · 1 comment
Open

Returning null when using iPhone device #6

nonoumasy opened this issue Jul 11, 2021 · 1 comment

Comments

@nonoumasy
Copy link

nonoumasy commented Jul 11, 2021

I used the code in the AddPostScreen.js.
Everything works in the simulator. An image gets uploaded successfully in Firebase storage.
However, when I use my iPhone 8 device, it will work up to the part where I select the photo, it will display the photo selected, it will submit, show the success alert but after that it's returning null and it does NOT upload to Firebase Storage.

My Firebase security rules is not strict and allows writes if request.auth.uid != null;

import {
  ActivityIndicator,
  Alert,
  Image,
  KeyboardAvoidingView,
  Platform,
  SafeAreaView,
  StyleSheet,
  Text,
  View,
} from 'react-native';
import { Controller, useForm } from 'react-hook-form';
import React, { useState } from 'react';

import { Button } from 'react-native-elements';
import FormButton from '../components/FormButton';
import FormInput from '../components/FormInput';
import ImagePicker from 'react-native-image-crop-picker';
// import ImagePicker from 'react-native-image-picker';
import { ScrollView } from 'react-native-gesture-handler';
import { addEntry } from '../lib/api';
import storage from '@react-native-firebase/storage';

export default function AddEntryScreen({ navigation, route }) {
  const { control, handleSubmit, errors, reset } = useForm();
  const [image, setImage] = useState(null);
  const [uploading, setUploading] = useState(false);
  const [transferred, setTransferred] = useState(0);

  const { id } = route.params;

  const onSubmit = async (data) => {
    try {
      const imageUrl = await uploadImage();
      console.log('Image Url: ', imageUrl);
      await addEntry({ id, data, imageUrl });
      Alert.alert(
        'Post published!',
        'Your post has been published Successfully!',
      );
      setImage(null);
    } catch (error) {
      console.warn(error);
    }
    reset();
    navigation.goBack();
  };

  const onPress = () => {
    reset();
    navigation.goBack();
  };

  const choosePhotoFromLibrary = () => {
    ImagePicker.openPicker({
      width: 1200,
      height: 780,
      cropping: true,
    }).then((image) => {
      console.log(image);
      const imageUri = Platform.OS === 'ios' ? image.sourceURL : image.path;
      setImage(imageUri);
    });
  };

  const uploadImage = async () => {
    if (image == null) {
      return null;
    }
    const uploadUri = image;
    let filename = uploadUri.substring(uploadUri.lastIndexOf('/') + 1);

    // Add timestamp to File Name
    const extension = filename.split('.').pop();
    const name = filename.split('.').slice(0, -1).join('.');
    filename = name + Date.now() + '.' + extension;

    setUploading(true);
    setTransferred(0);

    const storageRef = storage().ref(`photos/${filename}`);
    const task = storageRef.putFile(uploadUri);

    // Set transferred state
    task.on('state_changed', (taskSnapshot) => {
      console.log(
        `${taskSnapshot.bytesTransferred} transferred out of ${taskSnapshot.totalBytes}`,
      );

      setTransferred(
        Math.round(taskSnapshot.bytesTransferred / taskSnapshot.totalBytes) *
          100,
      );
    });

    try {
      await task;

      const url = await storageRef.getDownloadURL();

      setUploading(false);
      setImage(null);

      Alert.alert(
        'Image uploaded!',
        'Your image has been uploaded to the Firebase Cloud Storage Successfully!',
      );
      return url;
    } catch (e) {
      console.log(e);
      return null;
    }
  };

  return (
    <SafeAreaView>
      <KeyboardAvoidingView
        behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
        style={styles.container}>
        <ScrollView
          showsVerticalScrollIndicator={false}
          contentContainerStyle={{ width: '90%' }}>
          <Text>Add New Entry</Text>
          {image != null ? (
            <View>
              <Image
                source={{ uri: image }}
                resizeMode="cover"
                style={styles.image}
              />
            </View>
          ) : null}

          <Controller
            name="title"
            defaultValue={''}
            control={control}
            rules={{
              required: {
                value: true,
                message: 'Title is required',
              },
            }}
            render={({ onChange, value }) => (
              <>
                <FormInput
                  error={errors.title}
                  errorText={errors?.title?.message}
                  numberOfLines={1}
                  autoCapitalize={'sentences'}
                  placeholderText="Title"
                  onChangeText={(value) => onChange(value)}
                  value={value}
                />
                <Text style={{ color: '#ED5D5D' }}>
                  {errors.title && errors.title.message}
                </Text>
              </>
            )}
          />

          <Controller
            name="description"
            defaultValue={''}
            control={control}
            rules={{
              required: {
                value: true,
                message: 'description is required',
              },
              minLength: {
                value: 5,
                message:
                  'The minimum length for the description is 5 characters.',
              },
            }}
            render={({ onChange, value }) => (
              <>
                <FormInput
                  error={errors.description}
                  errorText={errors?.description?.message}
                  autoCapitalize={'sentences'}
                  multiline
                  numberOfLines={4}
                  style={styles.textArea}
                  placeholderText="Description"
                  onChangeText={(value) => onChange(value)}
                  value={value}
                />
                <Text style={{ color: '#ED5D5D' }}>
                  {errors.description && errors.description.message}
                </Text>
              </>
            )}
          />

          <Controller
            name="location"
            defaultValue={''}
            control={control}
            rules={{
              required: {
                value: true,
                message: 'Location is required',
              },
            }}
            render={({ onChange, value }) => (
              <>
                <FormInput
                  error={errors.location}
                  errorText={errors?.location?.message}
                  autoCapitalize={'words'}
                  placeholderText="Location"
                  onChangeText={(value) => onChange(value)}
                  value={value}
                />
                <Text style={{ color: '#ED5D5D' }}>
                  {errors.location && errors.location.message}
                </Text>
              </>
            )}
          />

          <FormButton
            onPress={choosePhotoFromLibrary}
            buttonTitle="Add Photo"
          />
          {uploading ? (
            <View style={{ justifyContent: 'center', alignItems: 'center' }}>
              <Text>{transferred} % Completed!</Text>
              <ActivityIndicator size="large" color="#333" />
            </View>
          ) : (
            <FormButton onPress={handleSubmit(onSubmit)} buttonTitle="Submit" />
          )}

          <View style={{ marginVertical: 10 }}>
            <Button
              title="Cancel"
              onPress={onPress}
              type="clear"
              titleStyle={{ color: '#26978A' }}
            />
          </View>
        </ScrollView>
      </KeyboardAvoidingView>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    justifyContent: 'center',
    alignItems: 'center',
  },
  header: {
    // flex: 1,
    flexDirection: 'row',
    marginTop: 20,
  },
  textArea: {
    height: 160,
    padding: 10,
    fontSize: 16,
    color: '#333',
    width: '100%',
  },
  image: {
    width: '100%',
    height: 240,
    borderRadius: 10,
    marginVertical: 10,
  },
});

@nonoumasy
Copy link
Author

nonoumasy commented Jul 12, 2021

ok I figured out a solution.
I used

const imageUri = Platform.OS === 'ios' ? image.path : image.path;

for both iOS as well and it worked.
Hope it helps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant