実現したいこと
現在、Reactnative expo firebaseを使用し、ボランティア掲示板アプリを作成するためにアプリを開発しています。iOSシュミレーター上では問題なく動き、Expo Goアプリを使用した実際のデバイスでも問題なく動きます。しかし、いざApp Storeに出すためにeasを使用してビルドすると、ビルドは成功するのですが、そのビルドしたアプリをスマホにTestFlightで入れてみると、アプリを開くときにクラッシュしてしまいます。ボランティア掲示板では、募集する側と応募する側の2つのアプリを作成していますが、募集する側ではアプリを開いたときにクラッシュし、応募側では、アプリは開けてログインも問題なくできますが、アカウントタブを開いた時にだけクラッシュします。調べてみましたが、なぜアプリを開いた時やアカウントタブを開いたときにクラッシュするのかが全く分かりません。提供しているソースコードとエラーコードは募集する側のアプリのコードです。
また、別件ですが、応募する側のアプリで、firebaseを使用して認証機能を載せているのですが、ログイン状態を保存できずにアプリを閉じたらまたログインしないといけないようになってしまいます。そこも解決したいです。
発生している問題・分からないこと
iOSシュミレーターやexpo goの実機では動くが、TestFlightになったらクラッシュする。
エラーメッセージ
error
1アプリ情報: 2app_name: app 3app_version: 1.0.3 4bundleID: com.takumigoodjob.voluncheer50orgdevelop 5platform: iOS 6os_version: iPhone OS 17.5.1 (21F90) 7device model: iPad13,16 8crashReporterKey: f3a6410320f70486a63784aaade5019310eb4bf5 9incident_id: ED3F4DCE-47EC-4A76-9CE7-17F69FB035A5 10 11 12プロセス情報: 13procName: app 14procPath: /private/var/containers/Bundle/Application/4227385E-F07F-493C-8E58-E645C6E3D8C9/app.app/app 15procRole: Foreground 16procLaunch: 2024-07-15 16:28:36.6178 +0900 17procStartAbsTime: 20982506251336 18procExitAbsTime: 20982511964457 19 20 21例外情報: 22exception: EXC_CRASH 23signal: SIGABRT 24termination: Abort trap: 6, byProc: app, byPid: 26552 25 26 27エラーメッセージ: 28libsystem_c.dylib: abort() called 29 30 31スレッド情報: 32faultingThread: 5 33queue: com.facebook.react.ExceptionsManagerQueue 34triggered: true 35 36 37クラッシュの原因: 38lastExceptionBacktrace: 39__exceptionPreprocess 40objc_exception_throw 41_dispatch_call_block_and_release 42_dispatch_client_callout
該当のソースコード
JavaScript
1文字数の都合上stylesheetとimportを一部省略しています。 2TouchableWithoutFeedback, Platform, Dimensions, Alert, ActivityIndicator } from 'react-native'; 3import { app, auth, db } from './firebase'; 4import { NavigationContainer } from '@react-navigation/native'; 5import { createNativeStackNavigator } from '@react-navigation/native-stack'; 6import { Feather } from '@expo/vector-icons'; 7import { TabLayout } from './TabLayout'; 8import AdminAuthScreen from './AdminAuthScreen'; 9import { useNavigation } from "@react-navigation/native"; 10import { getAuth, createUserWithEmailAndPassword, signInWithEmailAndPassword, onAuthStateChanged, signOut, sendPasswordResetEmail } from 'firebase/auth'; 11import { KeyboardAvoidingView } from 'react-native'; 12import { StripeProvider } from '@stripe/stripe-react-native'; 13import AsyncStorage from '@react-native-async-storage/async-storage'; 14 15const Stack = createNativeStackNavigator(); 16const screenWidth = Dimensions.get('window').width; 17const isTablet = screenWidth >= 768; 18 19const AuthScreen = ({ email, setEmail, password, setPassword, isLogin, setIsLogin, confirmEmail, setConfirmEmail }) => { 20 const navigation = useNavigation(); 21 const [showPassword, setShowPassword] = useState(false); 22 const [loading, setLoading] = useState(false); 23 24 const handleAuth = async () => { 25 setLoading(true); 26 try { 27 if (isLogin) { 28 await signInWithEmailAndPassword(auth, email, password); 29 await AsyncStorage.setItem('user', JSON.stringify(auth.currentUser)); 30 console.log('Saved user:', JSON.stringify(auth.currentUser)); // ここでユーザー情報をログ出力 31 navigation.navigate('AdminAuth'); 32 } else { 33 if (email !== confirmEmail) { 34 Alert.alert('エラー', 'メールアドレスが一致しません。'); 35 return; 36 } 37 await createUserWithEmailAndPassword(auth, email, password); 38 await AsyncStorage.setItem('user', JSON.stringify(auth.currentUser)); 39 console.log('Saved user:', JSON.stringify(auth.currentUser)); // ここでユーザー情報をログ出力 40 navigation.navigate('AdminAuth'); 41 } 42 } catch (error) { 43 let errorMessage = 'エラー'; 44 switch (error.code) { 45 // 各種エラーコードに対応したエラーメッセージ 46 // ... 47 default: 48 errorMessage = `認証中にエラーが発生しました。詳細:${error.message}`; 49 break; 50 } 51 Alert.alert('認証エラー', errorMessage); 52 } finally { 53 setLoading(false); 54 } 55 }; 56 57 const resetPassword = async () => { 58 if (!email) { 59 Alert.alert('エラー', 'メールアドレスを入力してください。'); 60 return; 61 } 62 63 try { 64 await sendPasswordResetEmail(auth, email); 65 Alert.alert('成功', 'パスワードリセットのメールを送信しました。メールを確認してください。'); 66 } catch (error) { 67 Alert.alert('エラー', 'パスワードリセット中にエラーが発生しました。'); 68 } 69 }; 70 71 return ( 72 <TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}> 73 <ImageBackground 74 source={require('./assets/背景.png')} 75 style={styles.all} 76 resizeMode="cover" 77 > 78 <Image source={require('./assets/Neko.png')} style={styles.image} /> 79 <View style={styles.authContainer}> 80 <Text style={styles.title}>{isLogin ? 'ログイン' : '新規登録'}</Text> 81 82 <View style={styles.inputContainer}> 83 <Feather name="mail" size={24} color="#ddd" style={styles.icon}/> 84 <TextInput 85 style={styles.input} 86 value={email} 87 onChangeText={setEmail} 88 placeholder="メールアドレス" 89 autoCapitalize="none" 90 /> 91 </View> 92 93 {!isLogin && ( 94 <View style={styles.inputContainer}> 95 <Feather name="mail" size={24} color="#ddd" style={styles.icon}/> 96 <TextInput 97 style={styles.input} 98 value={confirmEmail} 99 onChangeText={setConfirmEmail} 100 placeholder="メールアドレス確認" 101 autoCapitalize="none" 102 /> 103 </View> 104 )} 105 106 <View style={styles.inputContainer}> 107 <Feather name="lock" size={24} color="#ddd" style={styles.icon}/> 108 <TextInput 109 style={styles.input} 110 value={password} 111 onChangeText={setPassword} 112 placeholder="パスワード" 113 secureTextEntry={!showPassword} 114 autoCapitalize="none" 115 /> 116 <TouchableOpacity onPress={() => setShowPassword(!showPassword)}> 117 <Feather name={showPassword ? "eye-off" : "eye"} size={24} color="#ddd" style={styles.icon}/> 118 </TouchableOpacity> 119 </View> 120 121 <View style={styles.buttonContainer}> 122 <TouchableOpacity style={styles.button} onPress={handleAuth} disabled={loading}> 123 {loading ? <ActivityIndicator size="small" color="#fff" /> : <Text style={styles.buttonText}>{isLogin ? 'ログイン' : '新規登録'}</Text>} 124 </TouchableOpacity> 125 </View> 126 127 <Button 128 title={isLogin ? "新規登録へ" : "ログイン画面へ"} 129 onPress={() => setIsLogin(!isLogin)} 130 color="#3498db" 131 /> 132 133 {isLogin && ( 134 <TouchableOpacity onPress={resetPassword}> 135 <Text style={styles.resetPasswordText}>パスワードを忘れた場合</Text> 136 </TouchableOpacity> 137 )} 138 </View> 139 </ImageBackground> 140 </TouchableWithoutFeedback> 141 ); 142}; 143 144export default App = () => { 145 const [email, setEmail] = useState(''); 146 const [confirmEmail, setConfirmEmail] = useState(''); 147 const [password, setPassword] = useState(''); 148 const [user, setUser] = useState(null); 149 const [isLogin, setIsLogin] = useState(true); 150 151 const auth = getAuth(app); 152 153 useEffect(() => { 154 const checkUser = async () => { 155 const storedUser = await AsyncStorage.getItem('user'); 156 if (storedUser) { 157 console.log('Stored user:', storedUser); // ここで保存されたユーザー情報をログ出力 158 setUser(JSON.parse(storedUser)); 159 } 160 }; 161 162 const unsubscribe = onAuthStateChanged(auth, (currentUser) => { 163 setUser(currentUser); 164 if (currentUser) { 165 AsyncStorage.setItem('user', JSON.stringify(currentUser)); 166 console.log('Current user:', JSON.stringify(currentUser)); // ここで現在のユーザー情報をログ出力 167 } else { 168 AsyncStorage.removeItem('user'); 169 } 170 }); 171 172 checkUser(); 173 174 return () => unsubscribe(); 175 }, [auth]); 176 177 return ( 178 <StripeProvider publishableKey="pk_live_51PLF4tCIR7ZPZgETtbthtmAtuuTOWXjDQBGY1vznezimlSIy1TWJtOiqoK2mPirJMiKIpkzK6gIBgDlSD9Acqx7K00CEiZH3vn"> 179 <NavigationContainer> 180 <Stack.Navigator> 181 <Stack.Screen name="Auth" options={{ title: 'Authentication', headerShown: false }}> 182 {() => ( 183 <AuthScreen 184 isLogin={isLogin} 185 setIsLogin={setIsLogin} 186 email={email} 187 setEmail={setEmail} 188 confirmEmail={confirmEmail} 189 setConfirmEmail={setConfirmEmail} 190 password={password} 191 setPassword={setPassword} 192 /> 193 )} 194 </Stack.Screen> 195 <Stack.Screen name="AdminAuth" component={AdminAuthScreen} 196 options={{ 197 title: '管理者認証', 198 headerShown: false, 199 headerBackTitleVisible: false, 200 headerTitle: ' ' 201 }} 202 /> 203 <Stack.Screen name="TabLayout" component={TabLayout} options={{ headerShown: false }} /> 204 </Stack.Navigator> 205 </NavigationContainer> 206 </StripeProvider> 207 ); 208}
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
探した結果何も得れなかった。
補足
特になし
![guest](/img/icon/icnUserSample.jpg)
あなたの回答
tips
プレビュー