Bird
Raised Fist0
React Nativemobile~20 mins

SecureStore for sensitive data in React Native - Mini App: Build & Ship

Choose your learning style10 modes available
Build: Secure Data Storage
This screen lets users save and retrieve a secret message securely using SecureStore.
Target UI
┌───────────────────────────────┐
│ Secure Data Storage            │
├───────────────────────────────┤
│ Secret Message:               │
│ [__________________________]  │
│                               │
│ [Save Secret]  [Load Secret]  │
│                               │
│ Loaded Secret:                │
│ [__________________________]  │
└───────────────────────────────┘
Add a TextInput for user to enter a secret message.
Add a 'Save Secret' button that saves the message securely using SecureStore.
Add a 'Load Secret' button that retrieves the saved message and displays it.
Show the loaded secret below the buttons.
Handle errors gracefully with alerts.
Use React Native functional components and hooks.
Starter Code
React Native
import React, { useState } from 'react';
import { View, Text, TextInput, Button, Alert, StyleSheet } from 'react-native';
import * as SecureStore from 'expo-secure-store';

export default function SecureDataScreen() {
  const [secret, setSecret] = useState('');
  const [loadedSecret, setLoadedSecret] = useState('');

  // TODO: Implement saveSecret function

  // TODO: Implement loadSecret function

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Secret Message:</Text>
      <TextInput
        style={styles.input}
        value={secret}
        onChangeText={setSecret}
        placeholder="Enter your secret"
        secureTextEntry={true}
        accessibilityLabel="Secret message input"
      />
      <View style={styles.buttonRow}>
        <Button title="Save Secret" onPress={() => {}} />
        <Button title="Load Secret" onPress={() => {}} />
      </View>
      <Text style={styles.title}>Loaded Secret:</Text>
      <Text style={styles.loadedText} accessibilityLabel="Loaded secret text">{loadedSecret}</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, padding: 20, justifyContent: 'center' },
  title: { fontSize: 18, marginBottom: 8 },
  input: { borderWidth: 1, borderColor: '#ccc', padding: 10, marginBottom: 12, borderRadius: 4 },
  buttonRow: { flexDirection: 'row', justifyContent: 'space-between', marginBottom: 20 },
  loadedText: { fontSize: 16, color: '#333' }
});
Task 1
Task 2
Task 3
Task 4
Task 5
Solution
React Native
import React, { useState } from 'react';
import { View, Text, TextInput, Button, Alert, StyleSheet } from 'react-native';
import * as SecureStore from 'expo-secure-store';

export default function SecureDataScreen() {
  const [secret, setSecret] = useState('');
  const [loadedSecret, setLoadedSecret] = useState('');

  async function saveSecret() {
    try {
      if (!secret) {
        Alert.alert('Please enter a secret to save.');
        return;
      }
      await SecureStore.setItemAsync('userSecret', secret);
      Alert.alert('Secret saved securely!');
      setSecret('');
    } catch (error) {
      Alert.alert('Error saving secret:', error.message);
    }
  }

  async function loadSecret() {
    try {
      const result = await SecureStore.getItemAsync('userSecret');
      if (result) {
        setLoadedSecret(result);
      } else {
        Alert.alert('No secret found.');
        setLoadedSecret('');
      }
    } catch (error) {
      Alert.alert('Error loading secret:', error.message);
    }
  }

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Secret Message:</Text>
      <TextInput
        style={styles.input}
        value={secret}
        onChangeText={setSecret}
        placeholder="Enter your secret"
        secureTextEntry={true}
        accessibilityLabel="Secret message input"
      />
      <View style={styles.buttonRow}>
        <Button title="Save Secret" onPress={saveSecret} />
        <Button title="Load Secret" onPress={loadSecret} />
      </View>
      <Text style={styles.title}>Loaded Secret:</Text>
      <Text style={styles.loadedText} accessibilityLabel="Loaded secret text">{loadedSecret}</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, padding: 20, justifyContent: 'center' },
  title: { fontSize: 18, marginBottom: 8 },
  input: { borderWidth: 1, borderColor: '#ccc', padding: 10, marginBottom: 12, borderRadius: 4 },
  buttonRow: { flexDirection: 'row', justifyContent: 'space-between', marginBottom: 20 },
  loadedText: { fontSize: 16, color: '#333' }
});

We use expo-secure-store to save and load sensitive data securely on the device. The saveSecret function saves the entered secret with setItemAsync. It checks if the input is empty and shows an alert if so. The loadSecret function retrieves the saved secret with getItemAsync and updates the displayed text. Both functions handle errors by showing alerts. The UI uses accessible labels and secure text entry for privacy.

Final Result
Completed Screen
┌───────────────────────────────┐
│ Secure Data Storage            │
├───────────────────────────────┤
│ Secret Message:               │
│ [***************         ]    │
│                               │
│ [Save Secret]  [Load Secret]  │
│                               │
│ Loaded Secret:                │
│ [My secret message       ]    │
└───────────────────────────────┘
User types a secret message in the input field.
Tapping 'Save Secret' stores the message securely and clears the input.
Tapping 'Load Secret' retrieves and shows the saved secret below.
If no secret is saved, an alert informs the user.
Errors during save/load show alerts.
Stretch Goal
Add a button to delete the saved secret securely.
💡 Hint
Use SecureStore.deleteItemAsync with the same key to remove the secret.

Practice

(1/5)
1. What is the main purpose of using SecureStore in a React Native app?
easy
A. To speed up app animations
B. To store large files like images and videos
C. To manage app navigation between screens
D. To safely save sensitive data like passwords and tokens on the device

Solution

  1. Step 1: Understand SecureStore's role

    SecureStore is designed to securely save sensitive data on mobile devices.
  2. Step 2: Identify correct use case

    It is perfect for storing passwords, tokens, and private keys, not for files or UI tasks.
  3. Final Answer:

    To safely save sensitive data like passwords and tokens on the device -> Option D
  4. Quick Check:

    SecureStore purpose = safe sensitive data storage [OK]
Hint: SecureStore is for sensitive data, not files or UI [OK]
Common Mistakes:
  • Confusing SecureStore with file storage
  • Thinking SecureStore manages UI or navigation
  • Using SecureStore for non-sensitive data
2. Which of the following is the correct syntax to save a value using SecureStore in React Native?
easy
A. SecureStore.storeItem('key', 'value');
B. SecureStore.save('key', 'value');
C. await SecureStore.setItemAsync('key', 'value');
D. await SecureStore.putItem('key', 'value');

Solution

  1. Step 1: Recall SecureStore method names

    The correct method to save data is setItemAsync, which returns a promise.
  2. Step 2: Check syntax correctness

    await SecureStore.setItemAsync('key', 'value'); uses await SecureStore.setItemAsync('key', 'value'); which is correct syntax.
  3. Final Answer:

    await SecureStore.setItemAsync('key', 'value'); -> Option C
  4. Quick Check:

    Save data = setItemAsync with await [OK]
Hint: Use setItemAsync with await to save data [OK]
Common Mistakes:
  • Using incorrect method names like save or putItem
  • Forgetting to use await with async methods
  • Calling methods without Async suffix
3. What will be the output of this code snippet?
await SecureStore.setItemAsync('token', 'abc123');
const token = await SecureStore.getItemAsync('token');
console.log(token);
medium
A. 'abc123'
B. undefined
C. null
D. Error: Method not found

Solution

  1. Step 1: Save a value with setItemAsync

    The code saves the string 'abc123' under the key 'token'.
  2. Step 2: Retrieve the saved value with getItemAsync

    Then it fetches the value for 'token', which returns 'abc123'.
  3. Final Answer:

    'abc123' -> Option A
  4. Quick Check:

    Save then get returns saved string [OK]
Hint: getItemAsync returns saved value if key exists [OK]
Common Mistakes:
  • Expecting undefined or null instead of saved value
  • Confusing method names or forgetting await
  • Assuming error if key exists
4. Identify the error in this code snippet that tries to delete a stored item:
SecureStore.deleteItem('userPassword');
medium
A. Method name should be deleteItemAsync and must be awaited
B. Key 'userPassword' must be a number, not string
C. deleteItem does not exist; use removeItem instead
D. No error; code is correct

Solution

  1. Step 1: Check method name for deleting data

    The correct method is deleteItemAsync, not deleteItem.
  2. Step 2: Remember async methods require await

    Since it returns a promise, it should be called with await.
  3. Final Answer:

    Method name should be deleteItemAsync and must be awaited -> Option A
  4. Quick Check:

    Delete method = deleteItemAsync with await [OK]
Hint: Use deleteItemAsync with await to remove data [OK]
Common Mistakes:
  • Using wrong method name deleteItem
  • Not awaiting async calls
  • Thinking key must be a number
5. You want to securely store a user's session token and then immediately retrieve it to verify. Which code snippet correctly does this with error handling?
hard
A. SecureStore.setItem('session', token); const saved = SecureStore.getItem('session'); console.log(saved);
B. try { await SecureStore.setItemAsync('session', token); const saved = await SecureStore.getItemAsync('session'); console.log(saved); } catch (e) { console.error(e); }
C. await SecureStore.saveItem('session', token); const saved = await SecureStore.getItemAsync('session'); console.log(saved);
D. try { SecureStore.setItemAsync('session', token); const saved = SecureStore.getItemAsync('session'); console.log(saved); } catch (e) { console.error(e); }

Solution

  1. Step 1: Use correct async methods with await

    Only try { await SecureStore.setItemAsync('session', token); const saved = await SecureStore.getItemAsync('session'); console.log(saved); } catch (e) { console.error(e); } uses setItemAsync and getItemAsync with await properly.
  2. Step 2: Include error handling with try-catch

    try { await SecureStore.setItemAsync('session', token); const saved = await SecureStore.getItemAsync('session'); console.log(saved); } catch (e) { console.error(e); } wraps calls in try-catch to handle possible errors safely.
  3. Step 3: Identify incorrect method names and missing awaits

    The other options use wrong method names or miss awaits causing errors or wrong behavior.
  4. Final Answer:

    Code with await and try-catch -> Option B
  5. Quick Check:

    Correct async calls + error handling = try { await SecureStore.setItemAsync('session', token); const saved = await SecureStore.getItemAsync('session'); console.log(saved); } catch (e) { console.error(e); } [OK]
Hint: Always await async SecureStore calls and use try-catch [OK]
Common Mistakes:
  • Not awaiting async methods
  • Using wrong method names like setItem or saveItem
  • Skipping error handling for async calls
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard