Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
RailsとFirebaseで作るリアルタイムチャット
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
moai
March 26, 2021
Programming
0
770
RailsとFirebaseで作るリアルタイムチャット
Railsとfirebaseでどのようにリアルタイムチャットを作ったのかを話します。
moai
March 26, 2021
Tweet
Share
More Decks by moai
See All by moai
プロダクトビジョンから作る機能を落とし込む
ryosukeyamazaki
2
500
with コロナは支社でも成果が出しやすい
ryosukeyamazaki
1
180
自分らしいリーダーシップ
ryosukeyamazaki
2
2.7k
エンジニアが始めるUX(5分版)
ryosukeyamazaki
0
250
広く複雑なプロダクトの 高速キャッチアップに取り組む
ryosukeyamazaki
0
9.7k
エンジニアが始めるUX
ryosukeyamazaki
3
10k
Other Decks in Programming
See All in Programming
Claude Code、ちょっとした工夫で開発体験が変わる
tigertora7571
0
200
Claude Codeセッション現状確認 2026福岡 / fukuoka-aicoding-00-beacon
monochromegane
4
390
モジュラモノリスにおける境界をGoのinternalパッケージで守る
magavel
0
3.4k
Codex の「自走力」を高める
yorifuji
0
180
AI駆動開発の本音 〜Claude Code並列開発で見えたエンジニアの新しい役割〜
hisuzuya
4
470
Ruby x Terminal
a_matsuda
7
570
Go1.26 go fixをプロダクトに適用して困ったこと
kurakura0916
0
320
TROCCOで実現するkintone+BigQueryによるオペレーション改善
ssxota
0
130
Python’s True Superpower
hynek
0
200
AI時代のソフトウェア開発でも「人が仕様を書く」から始めよう-医療IT現場での実践とこれから
koukimiura
0
130
ベクトル検索のフィルタを用いた機械学習モデルとの統合 / python-meetup-fukuoka-06-vector-attr
monochromegane
2
300
今更考える「単一責任原則」 / Thinking about the Single Responsibility Principle
tooppoo
3
1.4k
Featured
See All Featured
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
150
How to make the Groovebox
asonas
2
2k
We Have a Design System, Now What?
morganepeng
55
8k
Building AI with AI
inesmontani
PRO
1
760
The untapped power of vector embeddings
frankvandijk
2
1.6k
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.3k
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
1
1.9k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
54k
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.1k
Bootstrapping a Software Product
garrettdimon
PRO
307
120k
The Curse of the Amulet
leimatthew05
1
9.5k
Optimising Largest Contentful Paint
csswizardry
37
3.6k
Transcript
freee 株式会社 freee Slide Format RailsとFirebaseで作るリアルタイムチャット
• freee株式会社所属 • Engineer • 開発効率高めるのが好き • 趣味はrubocopの適用 山崎遼介 moai
Engineer 2
3 今日のゴール RailsとFirebaseで作るリアルタイムチャットの仕組みを紹介
4 前提 作りたい機能、技術stack
5 プロジェクト管理freee • プロジェクトにまつわる業務を楽にしたい
6 作るモチベーション • プロジェクトに関する情報を雑に記録する • 経営者 <-> プロジェクトマネージャー 間で気になったことを聞ける
7 •
8 技術スタック:前提 • Ruby on Rails • OpenApi • TypeScript
• React
9 課題
10 リアルタイムのチャットをどう作るか?(ざっくり) • つまりはポーリングどうするの? ◦ ロングポーリング? ◦ 世の中に有るイベントサブスクライブサービス使う? ◦ Firebase?(NEW!)
11 Firebase使う懸念は? • 個人情報はどこに置くのか? ◦ Firebaseに個人情報置く? ◦ 置くとするとセキュリティはどう担保する? • Railsとの連携はどうするのか?
◦ RailsとID連携?
12 Firebase使う懸念は? • 個人情報はどこに置くのか? ◦ Firebaseに個人情報置く? ◦ 置くとするとセキュリティはどう担保する? • Railsとの連携はどうするのか?
◦ RailsとID連携?
13 どうなったの?
14 アーキテクチャざっくり Data Fetch 個人情報のやり取り Event Publish イベントが 起こったことだけ
を通知 Event Subscribe イベントが 起きたことだけを受 信 新しい Event 有る?
15 Rails側擬似コード class TimeLineMessage < ApplicationRecord after_create_commit -> { Gcp::Firestore.client.col('timeline_notifications').doc.set(
identifier: "#{id}-timeline", created_at: Time.current ) } end
16 firebaseのデータ
17 JavaScript側擬似コード export const ChatContainer = (id) => { 2
const [timelines, setTimeLines] = React.useState([]); const [latestId, setLatestId] = React.useState(0); 3 const reloadTimeline = (id) => { Api.fetchTimeline(setTimeLines); setLatestId(id);}; 4 const usePushNotification(reloadTimeline) = firestore 5 .collection('timeline_notifications').where('identifier', '==', "${id}-timeline") 6 .limit(1).nSnapshot(querySnapshot => { 7 if( querySnapshot.docs[0].id !== latestId ) reloadTimeline(querySnapshot.docs[0].id); 8 }); 9 React.useEffect(() => { usePushNotification(reloadTimeline) } ); 10 return (<Table rows={timelines} />); }
18 良かったこと
19 サブスクライブ処理はfirebaseにおまかせできた 新しい Event 有る? ここはFirebase Client がやってくれる Data Fetch
個人情報のやり取り Event Subscribe イベントが 起きたことだけを受 信 Event Publish イベントが 起こったことだけ を通知
20 フロント側の処理はここだけ export const ChatContainer = (id) => { 2
const [timelines, setTimeLines] = React.useState([]); const [latestId, setLatestId] = React.useState(0); 3 const reloadTimeline = (id) => { Api.fetchTimeline(setTimeLines); setLatestId(id);}; 4 const usePushNotification(reloadTimeline) = firestore 5 .collection('timeline_notifications').where('identifier', '==', "${id}-timeline") 6 .limit(1).nSnapshot(querySnapshot => { 7 if( querySnapshot.docs[0].id !== latestId ) reloadTimeline(querySnapshot.docs[0].id); 8 }); 9 React.useEffect(() => { usePushNotification(reloadTimeline) } ); 10 return (<Table rows={timelines} />); }
21 Firebaseには顧客情報置かなくて済んだ class TimeLineMessage after_create_commit -> { Gcp::Firestore.client.col('timeline_notifications').doc.set( identifier: "#{id}-timeline",
created_at: Time.current ) } end 通知イベントのみFirebaseに連携
22 じつは
23 社内で先行事例が • Takumi Ohashi@_tohashi による Firebaseを使ってチャット機能を作る先行事例があった
24 まとめ
25 まとめ • FirebaseをEvent通知だけに限定して使うのはめちゃ良い • Railsと一緒に使う場合もそんなに悪くない。 ◦ ただ、ログイン連携は闇の気配。
Firebaseはいいね
27 EOF