質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

React Native

React Nativeは、ネイティブモバイルアプリ(iOS/Android)を作成できるJavaScriptフレームワークです。Reactと同じ設計のため、宣言的なコンポーネントでリッチなUIを開発することが可能です。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

780閲覧

gifted chatでmessageをDBからFetchしたい(react native)

yamady

総合スコア176

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

React Native

React Nativeは、ネイティブモバイルアプリ(iOS/Android)を作成できるJavaScriptフレームワークです。Reactと同じ設計のため、宣言的なコンポーネントでリッチなUIを開発することが可能です。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2018/04/18 05:57

閲覧いただきまして、ありがとうござますmm

React NativeとFirebaseでチャット機能を実装したいと考えています。
「RNでチャットを実装するならコレ!」というので名高い、gifted chatを使っているのですが最後の最後(?)で詰まってしまっています・・・。(泣

エラー(困っていること)

Firebaseに入っているroom(チャットルーム)に入っているmessages(メッセージ一覧)を取ってくることには成功しているが、messageに分けることができない。

開発環境&ソースコード

使っているライブラリ(バージョン)は下記となります。

react-native ^0.52.3 react-native-firebase 3.2.2 react-native-gifted-chat 0.4.3

Message.js

JavaScript

1/** 2* @flow 3* 4* The Message is a screen to communicate with User 5*/ 6import _ from 'lodash'; 7import React from 'react'; 8import { StyleSheet, TouchableOpacity, View, Text, ListView } from 'react-native'; 9import Icon from '../../ui/components/Icon'; 10import * as Theme from '../../theme'; 11import Screen from '../../ui/components/Screen'; 12import { sendMessage, messagesFetch } from '../../ui/redux/messageActions'; 13import firebase from 'react-native-firebase'; 14import { connect } from 'react-redux'; 15import { GiftedChat, Bubble, Send } from 'react-native-gifted-chat'; 16 17const styles = StyleSheet.create({ 18 headerIcon: { 19 paddingHorizontal: 15 20 } 21}); 22 23class Message extends React.Component { 24 static navigationOptions = ({ navigation }) => { 25 return { 26 headerTitle: `${navigation.state.params.room.user.name}`, 27 headerLeft: ( 28 <TouchableOpacity 29 onPress={()=> navigation.goBack()} 30 style={styles.headerIcon} 31 > 32 <Icon name='chevron-left' size={28} style={{color: '#fff'}}/> 33 </TouchableOpacity> 34 ), 35 headerStyle: { 36 backgroundColor: Theme.PRIMARY, 37 }, 38 headerTitleStyle: { 39 color: '#fff', 40 fontWeight: 'bold' 41 } 42 }; 43 }; 44 45 state = { 46 messages: [], 47 } 48 49 componentWillMount() { 50 const room = this.props.navigation.state.params.room; 51 this.props.messagesFetch(room); 52 53 this.createDataSource(this.props); 54 } 55 56 componentWillReceiveProps(nextProps) { 57 this.createDataSource(nextProps); 58 } 59 60 createDataSource({ messages }) { 61 const ds = new ListView.DataSource({ 62 rowHasChanged: (r1, r2) => r1 !== r2 63 }); 64 65 this.dataSource = ds.cloneWithRows(messages); 66 // ここまでのmessagesは配列で取ってこれている 67 console.log('messages', messages); 68 } 69 70 onSend = (message) => { 71 const room = this.props.navigation.state.params.room; 72 // this.setState((previousState) => ({ 73 // messages: GiftedChat.append(previousState.messages, messages), 74 // })); 75 this.props.sendMessage({ 76 message, 77 room 78 }); 79 } 80 81 // ここでエラーになる(messageが取れてない) 82 componentDidMount(message) { 83 this.setState((previousState) => { 84 return { 85 messages: GiftedChat.append(previousState.messages, message), 86 }; 87 }); 88 }; 89 90 render() { 91 const { currentUser } = firebase.auth(); 92 return ( 93 <Screen> 94 <GiftedChat 95 messages={this.state.messages} 96 onSend={this.onSend.bind(this)} 97 user={{ 98 _id: currentUser.uid 99 }} 100 /> 101 </Screen> 102 ); 103 } 104} 105 106const mapStateToProps = (state) => { 107 const messages = _.map(state.messages, (val, uid) => { 108 return { ...val, uid }; 109 }); 110 111 const { text, user, createdAt, _id } = state.messageForm; 112 return { text, user, createdAt, _id, messages }; 113}; 114 115export default connect(mapStateToProps, { 116 sendMessage, 117 messagesFetch 118})(Message); 119

messageActions.js

JavaScript

1/** 2* Builds an action to request 3*/ 4export const sendMessage = ({ message, room }) => { 5 const { currentUser } = firebase.auth(); 6 return (dispatch) => { 7 firebase.database().ref(`/rooms/${room.roomId}/messages/`) 8 .push({ 9 text: message[0].text, 10 user: message[0].user, 11 createdAt: firebase.database.ServerValue.TIMESTAMP, 12 }) 13 .then(() => { 14 dispatch({ type: 'message_create' }); 15 }); 16 } 17} 18 19/** 20* Builds an action to notification fetch action 21*/ 22export const messagesFetch = (room) => { 23 return (dispatch) => { 24 firebase.database().ref(`/rooms/${room.roomId}/messages/`) 25 .once('value', snapshot => { 26 dispatch({ type: 'messages_fetch_success', payload: snapshot.val() }) 27 }); 28 }; 29};

参考ソース

↓ Gifted Chatの著者がやっているチュートリアル
https://www.youtube.com/watch?v=VTnFDc3IFag
https://github.com/FaridSafi/ChatApp

こちらはreduxを使っていないのですが、reduxを使ってできないものかと・・・。
そもそも、このやり方で合っているかの不安もあります(汗)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

 // ここでエラーになる(messageが取れてない) componentDidMount(message) { this.setState((previousState) => { return { messages: GiftedChat.append(previousState.messages, message), }; }); };

componentDidMount()の第一引数には何も渡ってこないはずです。
https://reactjs.org/docs/react-component.html#componentdidmount

なので、そこでmessageが取れないのは当然かと思います。

また、componentDidMount()の中で、previousState.messagesstateの中のmessagesを参照しようとしていますが、このライフサイクルのタイミングではまだ、state内のmessages[]と空の配列のままですよね?

componentWillMount() { const room = this.props.navigation.state.params.room; this.props.messagesFetch(room); this.createDataSource(this.props); }

componentDidMount()の前に呼ばれるcomponentWillMount()では、this.createDataSource(this.props)を呼んでいて、このthis.propsの中にmessageが含まれているのですよね? そして、このmessagecomponentDidMountの中で参照したいという訳なのですよね?

であれば、componentWillMountの中でstateの中にmessageを入れるか、もしくは、componentWillMountでやっていることをcomponentDidMountの方に移してしまうかすればよいのではないでしょうか。

投稿2018/04/18 06:18

HayatoKamono

総合スコア2415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yamady

2018/04/18 06:46

ご丁寧な回答ありがとうございます。 非常にわかりやすかったです。 ``` componentWillMount() { const room = this.props.navigation.state.params.room; this.props.messagesFetch(room); this.createDataSource(this.props); this.setState((previousState) => { return { messages: GiftedChat.append(previousState.messages, message), }; }); } ``` これだと当然、messagesからmessageを取り出す作業を定義しなければならないと思うのですが、Reactで配列から全てを取り出すのに最適なやり方って何があるのでしょうか><(roomのmessagesのなかに、messageアイテムがたくさん入っている感じなのですが。。)今まではListViewのrenderRowでできていたのですが。。。汗
HayatoKamono

2018/04/18 06:54

ごめんなさい、質問の意味がよく理解出来ていません。質問本文の方にコードを交えて、コメントで頂いている質問をもう少し詳しく、かつ、整理しつつ追記頂くことは可能ですか?
HayatoKamono

2018/04/18 07:41

ちなみに、もし最初の回答で今回の質問自体は解決でしたら、コメント欄で頂いた内容は別質問に分けて頂けると助かります。
yamady

2018/04/18 20:35

Hayatoさん、いつもご回答ありがとうございます。 ご指摘いただいた通りですね!すみませんm(_ _)m 別途質問を作成していきます!ありがとうございます!!
HayatoKamono

2018/04/18 20:41

了解致しました!ありがとうございます!
HayatoKamono

2018/04/18 20:57

あ、すみません!「Hayatoさんいつもありがとうございます」は嬉しいのですが、これあると他の人が回答しづらくなると思うので、消して頂けませんでしょうか?よろしくお願い致します!今からまた寝るので明日(今日)、改めて質問みてみますね。
yamady

2018/04/18 21:00

すみません、すぐに削除しますね!ごめんなさい!
HayatoKamono

2018/04/18 21:08

ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問