DEV Community

Cover image for RN: Amplify Auth & Storage
Mike Oristian
Mike Oristian

Posted on

1 1

RN: Amplify Auth & Storage

I'm trying to understand how to configure AWS Amplify React Native projects so that the <S3Image/> and <S3Album/> components work properly. I thought I'd write a blog post with questions and then update it with the answers I get from the Amplify community.

It's a simple Profile screen I'm trying to manage, with a list of all the recent uploads to the S3 bucket. I'd like to know I have the permission configured properly for upload and viewing, then explore how I should store the S3 Image pathways (or keys) in DataStore such that I have a foolproof way to display the current user's profile picture as well as any other profile's picture (even if they upload to a 'protected' directory)

I've set this storage up with the amplify-cli but I'd like to know how to double check that CORS and the Bucket's policies are correctly assigned for access via the app's Amplify toolkit.

import React, { useState, useEffect } from 'react';
import { View, Text, Image, Button, ActivityIndicator } from 'react-native';

import Amplify from '@aws-amplify/core';
import Auth from '@aws-amplify/auth';
import { Storage } from 'aws-amplify'
import { S3Image, S3Album } from 'aws-amplify-react-native'
import config from '../../aws-exports';
Amplify.configure(config);

import { 
launchCamera, 
launchImageLibrary } from 'react-native-image-picker';

import defaultAvatar from '../assets/images/defaultAvatar.png'


Amplify.configure({
    Storage: {
        AWSS3: {
            bucket: 'XXXXXXXXXXX-staging',
            region: 'us-west-2',
        }
    },
    Auth: {
        region: 'us-west-2', Region
        userPoolId: 'YYYYYYYYYYYY'
    },

    Analytics: {
        disabled: true,
    }
})
Enter fullscreen mode Exit fullscreen mode

Here is my main component below - and here are my questions

  • I'm able to print out my currentAuthenticatedUser's attributes, but how is this user passed to the S3Image call and the Storage call?
  • I'm getting 403 errors for the most part, but I can see the images getting uploaded, just not shown on the useEffect retrieval
  • What are the checklists to run through to ensure CORS and Bucket Policy (json) is set correctly for access?
  • Should we be importing from @aws-amplify or 'aws-amplify' with deconstructors ({Auth})
  • Lastly, if Storage is configured at {level: 'protected'} then how will other users be able to use the key I need to store in DataStore
const Profile = ({ navigation }) => {
    const [avatar, setAvatar] = useState(defaultAvatar);
    const [avatarFileName, setAvatarFileName] = useState('')
    const [allUploads, setAllUploads] = useState([])

    const handlePicker = () => {
        launchImageLibrary({ mediaType: 'photo' }, (response) => {
            console.log('Response = ', response);

            if (response.didCancel) {
                console.log('User cancelled image picker');
            } else if (response.error) {
                console.log('ImagePicker Error: ', response.error);
            } else if (response.customButton) {
                console.log('User tapped custom button: ', response.customButton);
            } else {
                setAvatar({ uri: response.uri });
                setAvatarFileName(response.fileName);
            }
        });
    };

    const uploadImageAsync = async (pickerResult) => {
        try {
            console.log(avatar)
            const profileFile = await fetch(avatar.uri);
            const blob = await profileFile.blob();
            console.log('*** gonna post ' + avatarFileName)
            Storage.put(avatarFileName, blob)
                .then(result => console.log(result))
                .catch(err => console.log(err))
        }
        catch (e) {
            console.log('Something errored ' + e)

        }
    }

    useEffect(() => {
        Storage.list('', { level: 'protected' })
            .then(results => {
                console.log('s3 list callback')
                setAllUploads(results);
                console.log(results)
            })

        Auth.currentAuthenticatedUser()
            .then(user => {
                console.log(user.attributes.phone_number)
            })
    }, [])


    return (
        <>
            <View style={{ justifyContent: 'center', flexDirection: 'row' }}>
                {allUploads && allUploads.map((upload, i) => (
                    <S3Image key={i} imgKey={upload.key} style={{ width: 100, height: 100 }} />
                ))}
            </View>
            <View>
                <Image
                    source={avatar}
                    PlaceholderContent={<ActivityIndicator />}
                    style={{ width: 400, height: 400 }}
                />
                <Button title='Choose Picture' onPress={() => { handlePicker() }} />
                <Button title='Upload Picture' onPress={() => { uploadImageAsync(avatar) }} />

            </View>
        </>
    )
}

export default Profile;
Enter fullscreen mode Exit fullscreen mode

Thanks in advance for taking a look and helping me clarify the proper way to use these components in React Native

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

While many AI coding tools operate as simple command-response systems, Qodo Gen 1.0 represents the next generation: autonomous, multi-step problem-solving agents that work alongside you.

Read full post

Top comments (0)

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

Rather than just generating snippets, our agents understand your entire project context, can make decisions, use tools, and carry out tasks autonomously.

Read full post

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay