Serverless Mobile App Development -1

Abdullatif Topçu
Geek Culture
Published in
7 min readSep 13, 2021

This is a two-part article series. The second part of this series which is about AWS Services and Backend is on the way.

React Native - AWS Lambda - Dynamodb - S3

Hi There,

In this article, I will introduce a mobile application that I made in the past. I’m thinking of moving forward by showing some theory and some code. I hope it will be useful to someone.

I will not teach React Native or AWS Lambda in this article. People who need it can look at different resources.

Again, in this article, I will not explain the details one by one. Such a detailed explanation means a long series. Unfortunately, I don’t have that much time right now, but hopefully in the future.

I am writing this article for those who know React Native and AWS at least at the entry-level. Only AWS knowledge is sufficient. No need to know Lambda. In this article, I will be showing more codes. There will be no narration :(

Please contribute with your questions and suggestions. Good reading

The App

This application is developeda solution for the education sector. I developed a mobile application where students preparing for exams can ask questions. After the student asks a question, a notification is sent to the phone of the relevant teacher according to the selected lesson type. Then the teacher solves the question and uploads it to the application. The student receives a solution notification.

Why did I use React Native in the application?

In recent years, React Native has started to make a name for itself among the libraries used for mobile application development. Writing with JS, compiling common code for Android and IOS, and simplicity are the highlights for me. If you like JS or TS, React Native is for you.

The React Native Template That I selected: Now UI React Native Template

Design is important in mobile application development. We, the developers are not designers and I think it is best to leave this job to the experts. For this reason, I found and used the attached template among the free react native templates I was looking for on the web. It is very robust, clear, extendable, and easy to learn. I highly recommend it.

Project Code Repo

You may find and download the codes of the project here. Contributions are welcome as well.

React Native Folder Structure and Important Files

The file structure that comes when you create an empty React Native project is quite sufficient for general projects. Two of the important files in a react native project are package.json, package-lock.json files. These are the files that contain the list and versions of the js libraries you will use in your react-native project. One Note; Before starting a React Native project, you need to install a package manager. I use Node Package Manager in my project.

You may find the whole React-Native related codes under the folder bulutasor/BulutaSorFrontend2. Here are the folders that should be examined:

screens: All screen codes are under this folder.

Sample Screens Code:

/* eslint-disable no-console */
import React from 'react';
import {
StyleSheet, Dimensions, ScrollView, Alert
} from 'react-native';// cache app images

// import * as Notifications from 'expo-notifications';
import { connect } from 'react-redux';
import {
Block, Text, theme, withGalio
} from 'galio-framework';
import AnimatedLoader from 'react-native-animated-loader';
import { Card } from '../components';

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

class StudentsSolvedQuestionListScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
visible: false,
error: null,
};
}

componentDidMount() {
this.state.visible = false;
this.state.error = null;
}

renderArticles = () => {
const { error } = this.state;
const { questions } = this.props;
return (

<ScrollView showsVerticalScrollIndicator={false} contentContainerStyle={styles.articles}>
<Block flex>
{error ? <p>{error.message}</p> : null}
{
(Array.isArray(questions))
? questions.filter((item) => item.state === 'passive').map(
(question) => <Card item={question} key={question.s3Key} cevapGoster="true" horizontal />
)
: (
<Text>
Henüz çözülmüş bir sorun yok.
</Text>
)
}
</Block>
</ScrollView>
);
};

render() {
const { visible } = this.state;
return (
<ScrollView showsVerticalScrollIndicator={false} contentContainerStyle={styles.articles}>
<Block flex style={styles.home}>
<Block center style={{ flex: 30 }}>
<AnimatedLoader
visible={visible}
overlayColor="rgba(255,255,255,0.75)"
source={require('./spinner.json')}
animationStyle={styles.lottie}
speed={1}
/>
{this.renderArticles()}
</Block>
</Block>
</ScrollView>
);
}
}

const styles = StyleSheet.create({
home: {
width,
},
articles: {
width: width - theme.SIZES.BASE * 2,
paddingVertical: theme.SIZES.BASE,
paddingHorizontal: 2,
fontFamily: 'montserrat-regular',
},
});

function mapStateToProps(storeState) {
return {
userName: storeState.userName,
password: storeState.password,
questions: storeState.questions
};
}

function mapDispatchToProps() {
return {
// setQuestions()
};
}
export default withGalio(connect(mapStateToProps, mapDispatchToProps)(StudentsSolvedQuestionListScreen));

components: Under this folder, you can find the component library that comes with the React Native template.

import React, { useState } from 'react';
import {
Alert,
Modal,
StyleSheet,
TouchableWithoutFeedback,
Keyboard,
View,
Dimensions,
TouchableOpacity,
} from 'react-native';
import {
Text, theme, Block
} from 'galio-framework';
import { useNavigation } from '@react-navigation/native';
import { useSelector } from 'react-redux';
import ArButton from './Button';
import Icon from './Icon';
import nowTheme from '../constants/Theme';

const DismissKeyboard = ({ children }) => (
<TouchableWithoutFeedback onPress={() => Keyboard.dismiss()}>{children}</TouchableWithoutFeedback>
);

const { width, height } = Dimensions.get('screen');

const SessionBar = (props) => {
const [modalVisible, setModalVisible] = useState(0);
const user = useSelector((state) => state.user);
const navigation = useNavigation();
let userType = 'Öğrenci';
const { isTeacher } = user;
if (isTeacher) {
userType = 'Öğretmen';
}
console.log(`isTeacher:${isTeacher}`);
console.log(`userType:${userType}`);
return (
<Block>
<Modal
animationType="slide"
visible={modalVisible}
style={styles.modalView}
transparent
onRequestClose={() => {
Alert.alert('Modal has been closed.');
}}
>
<View
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
margin: 80,
padding: 80,
borderColor: nowTheme.COLORS.BLACK,
borderRadius: 10,
backgroundColor: nowTheme.COLORS.WHITE,
}}
>
<ArButton
color="info"
round
style={styles.createButton}
onPress={() => { setModalVisible(false); }}
title="Kapat"
>
<Text
style={{ fontFamily: 'montserrat-bold' }}
size={14}
color={nowTheme.COLORS.WHITE}
>
Kapat
</Text>
</ArButton>
<Block>
<Text
size={16}
muted
style={{
width: '100%',
color: '#2c2c2c',
fontWeight: 'bold',
lineHeight: 20,
fontSize: 19,
fontFamily: 'montserrat-bold',
margin: 10,
zIndex: 2,
textAlign: 'center',
}}
>
{userType}
</Text>
<Text
size={16}
muted
style={{
width: '100%',
color: '#2c2c2c',
fontWeight: 'bold',
lineHeight: 20,
fontSize: 19,
fontFamily: 'montserrat-bold',
margin: 10,
zIndex: 2,
textAlign: 'center',
}}
>
{user.userName}
</Text>
</Block>
<ArButton
color="primary"
round
style={styles.createButton}
onPress={() => { setModalVisible(false); logout(); navigation.navigate('LoginScreen'); }}
title="Oturumu Kapat"
>
<Text
style={{ fontFamily: 'montserrat-bold' }}
size={14}
color={nowTheme.COLORS.WHITE}
>
Oturumu Kapat
</Text>
</ArButton>
</View>
</Modal>
<Block flex row right>
<TouchableOpacity
style={[styles.profileButton]}
onPress={() => {
setModalVisible(true);
}}
>
<Text>{user.userName}</Text>
<Icon
family="NowExtra"
size={16}
name="basket2x"
color={nowTheme.COLORS.WHITE}
/>

</TouchableOpacity>
</Block>
</Block>
);
};
export default SessionBar;

const styles = StyleSheet.create({
registerContainer: {
marginTop: 55,
width: width * 0.9,
height: height < 812 ? height * 0.8 : height * 0.8,
backgroundColor: nowTheme.COLORS.WHITE,
borderRadius: 4,
shadowColor: nowTheme.COLORS.BLACK,
shadowOffset: {
width: 0,
height: 4,
},
shadowRadius: 8,
shadowOpacity: 0.1,
elevation: 1,
overflow: 'hidden',
},

centeredView: {
flex: 1,
justifyContent: 'flex-start',
alignItems: 'center',
margin: 20,
backgroundColor: nowTheme.COLORS.WHITE,
padding: 20,
},
modalView: {
backgroundColor: theme.COLORS.WHITE,
borderRadius: 20,
margin: 35,
padding: 35,
height: height * 0.6,
width: width * 0.6,
justifyContent: 'flex-start',
alignItems: 'stretch',
borderColor: theme.COLORS.BLACK,

},
openButton: {
backgroundColor: theme.COLORS.WHITE,
borderRadius: 20,
padding: 10,
elevation: 2
},
title: {
flex: 2,
height: height * 0.07,
alignItems: 'center',
justifyContent: 'center',
},
titleTextStyle: {
fontWeight: '400',
fontSize: theme.SIZES.FONT * 2,
color: theme.COLORS.BLACK,
paddingTop: 20
},

createButton: {
width: width * 0.5,
marginTop: 25,
marginBottom: 40,
},

profileButton: {
padding: 12,
position: 'relative',
width: width * 0.2,
},

cikisButton: {
padding: 12,
position: 'relative',
width: width * 0.2,
}
});

Android and IOS: In these folders, you can find environment-specific configurations produced from react-native codes during compilation. Some third-party library uses require operating-system-specific settings. In this case, the codes we will intervene in are here. Under normal circumstances, we do not make any development in these folders.

Appium: When we develop a mobile application, we need to test our application on different devices. Because in general, our application may work very differently depending on the operating system model and version, memory, and screen size, or worse, it may not work. :( It can be very useful to test our application in a device farm in order to catch this situation before the end-users experience it in our application. I definitely recommend it. You can find AWS Device Farm here.

Redux

Redux is a data store. It’s usually good practice to separate data with application screens. In this way, data consistency is ensured between screens, or between different components on the same screen. Redux is now a must-use component in JS libraries such as React Native, Vue, or Angular. You can access the details from the addresses below.

And one Turkish Article From Zafer Ayan

Conclusion

In this article, I tried to present my mobile App’s react-native Code, maybe it will inspire someone. In the second article of this series, I will explain Backend.

Wish you all a lovely life

--

--