tmp
Showing posts with label
Firebase
.
Show all posts
Showing posts with label
Firebase
.
Show all posts
Friday, February 15, 2019
AniHani.link の技術選定メモ
## 方針 あにハニでも いつから.link っぽいの欲しい -> 作る? バックエンドをごりごりやりたくないのでなるべく baas(Firebase) を利用 フロントに集中 産物: https://fiahfy-anihani.firebaseapp.com ソース: https://github.com/fiahfy/anihani-link ### Database Firestore, nosql 使いたかったからそれで データは正規化しないほうがいいみたいだけど更新時にupdateし直すのがどうしてもめんどいのとjoinするデータがそもそも少ないので参照値を利用してる ただしデータ取得の実装によってはフロントでのリクエストが結構増える ### Batch ツイートを取ってきてパースしていい具合にDBにぶちこむ一番面倒な部分 Firebase Functions でそれっぽいことができるのでそこで実行 当初は Spark plan (無料枠) でなんとかしようと思ったが Functions から Googleネットワーク外への送信が不可(受信はOK) -> GAEで実行すればいいんじゃね? -> Deploy時に利用する Build API が課金状態じゃないと使えない = 自動的に Braze plan (従量制) -> Braze plan なら Firebase Functions でいいじゃん となり Firebase Functions に戻る 定期実行の仕組みが必要だがいくつかパターンがある模様 * `cron-job.org` から HTTPS リクエストを送信してフックで実行 * GAEをたてて cron service でGAEにリクエスト -> pub/sub か https 送信 -> functions でフック * Cloud Scheduler で pub/sub か https 送信 -> functions でフック 一番いまどきっぽいので Cloud Scheduler を選択 1アカウントにつき 月3つのjobまでは無料 超えてもそんなに高くない Cloud Scheduler で pub/sub に定期的にメッセージ送信 https でフックしてもいいけどその場合トークンかなんかでパスワードかけとかないと誰かから叩かれる ### Front-end `Vue.js`, `Nuxt.js` を選択、個人的に小さいサービスなら TypeScript すら面倒 + Vue.js とあまり相性が良くないので pure js (ES6) というか TypeScript 導入するくらいなら `React.js`, `Next.js` の方がよさげ module をいくつかつっこむ * `@nuxtjs/dotenv` `.env` 用 * `@nuxtjs/google-analytics` GA用 * `@nuxtjs/pwa` PWAとかmetaとかiconとか用 * `@nuxtjs/vuetify` マテリアルデザイン+component あとは firebase を plugin で初期化して firestore からデータを取得して表示 SSR はサイトの特性上恩恵があまりないのと面倒なのでなし 静的ホスティングで済ませたかったので `nuxt generate` してどこかにあげる generate する場合は `mode: spa` にするもんかと勝手に思ってたけど `universal` で恩恵があるっぽい(要調査 https://qiita.com/amishiro/items/11bd642728f6b5838189#universalssr%E3%83%A2%E3%83%BC%E3%83%89%E3%81%A7%E4%BD%9C%E6%88%90 ### Hosting 静的ファイルをあげられればぶっちゃけどこでもいい 候補は Github Pages, Netlify, Firebase Hosting ググったら Netlify はたまに詰まるっていうのと Firebase Hosting は裏で Fastly 使ってるよってことだったので Firebase Hosting を選択 (ここだけ別管理にしても面倒なので) ## 構成 ``` +------+ | User | +------+ ^ | v +-----------------------------+ | Firebase Hosting(Nuxt.js) | +-----------------------------+ ^ | v +----------------------+ +------------+ | Firebase Firestore | <-> | CLI(Local) | +----------------------+ +------------+ ^ | v +----------------------+ | Firebase Functions | +----------------------+ ^ | +-------------------+ | Cloud Scheduler | +-------------------+ ``` ## TODO ツイートのパースがガバガバすぎてスケジュールの変更、キャンセルがうまく取れない あにまーれだけに関していうと 非公式wiki に綺麗なスケジュールがあるのでそっちから取る方がいいかも こだわると時間かかりそうだったのでフロントの実装が雑(ここは適宜) キャッシュ制御もしてない vuex もほとんど利用できてない iPhoneX で PWA で起動すると SafeArea に余裕で食い込む standaloneかどうか と portrait/landscape と iPhoneXかどうか が取れれば後は CSS でがんばればなんとかなりそうな気はする ログインシステム(認証) はそもそもメンバーが少ない(9人)からいらないでしょってことで省略 Bookmark 的なものが必要になっても local storage でいいんじゃね? という感じ それでも必要になったら Firebase Authentication DevOps?知らない子ですね...
Thursday, August 16, 2018
Web Push (Firebase Cloud Messaging)
Web Push に Firebase Cloud Messaging を利用した場合の実装 ### Set gcm_sender_id Firebase project を作成して `103953800507` (固定値) を指定 ドキュメントではこの固定値を入力するように記載されているが省略しても動作はする(謎) `manifest.json` ``` { : "gcm_sender_id": "103953800507" } ``` ### initialize firebase app Firebase project の設定値を指定 `index.html` ``` ``` `app.js` ``` // Retrieve Firebase Messaging object. const messaging = firebase.messaging() ``` ### register service worker ServiceWorker を `/firebase-messaging-sw.js` とする場合は firebase がよろしくやってくれるので省略可 `app.js` ``` navigator.serviceWorker.register('sw.js') .then((registration) => { messaging.useServiceWorker(registration) }) ``` ### request permission and get token `app.js` ``` messaging.requestPermission() .then(() => { console.log('Notification permission granted.') messaging.getToken() .then((currentToken) => { if (currentToken) { sendTokenToServer(currentToken) } else { // Show permission request. console.log('No Instance ID token available. Request permission to generate one.') // Show permission UI. sendTokenToServer(false) } }) .catch((err) => { console.log('An error occurred while retrieving token. ', err) sendTokenToServer(false) }) }) .catch((err) => { console.log('Unable to get permission to notify.', err) }) ``` ### receive push タブの状態(フォアグラウンド/バックグラウンド)に応じて処理する場所が違うのでそれぞれ実装 #### receive on foreground `app.js` ``` messaging.onMessage((e) => { console.log('Message received. ', e) const title = 'Title' const options = { body: e.data.text } new Notification(title, options) }) ``` #### receive on background `sw.js` ``` // Give the service worker access to Firebase Messaging. // Note that you can only use Firebase Messaging here, other Firebase libraries // are not available in the service worker. importScripts('https://www.gstatic.com/firebasejs/5.3.1/firebase-app.js') importScripts('https://www.gstatic.com/firebasejs/5.3.1/firebase-messaging.js') // Initialize the Firebase app in the service worker by passing in the // messagingSenderId. firebase.initializeApp({ 'messagingSenderId': "
" }) // Retrieve an instance of Firebase Messaging so that it can handle background // messages. const messaging = firebase.messaging() messaging.setBackgroundMessageHandler((e) => { console.log('Message received. ', e) // Customize notification here const title = 'Title' const options = { body: e.data.text } return self.registration.showNotification(title, options) }) ``` ### send push `firebase-admin` を利用、 Firebase の サーバアカウントキーをダウンロードし `key.json` にリネーム `'TOKEN'` に対象の登録トークンを指定 `main.js` ``` const admin = require('firebase-admin') const serviceAccount = require('./key.json') admin.initializeApp({ credential: admin.credential.cert(serviceAccount) }) // See documentation on defining a message payload. const message = { data: { text: 'Here is a payload!' }, token: 'TOKEN' } // Send a message to the device corresponding to the provided // registration token. admin.messaging().send(message) .then((response) => { // Response is a message ID string. console.log('Successfully sent message:', response) }) .catch((error) => { console.log('Error sending message:', error) }) ``` 送信 ``` node main.js ```
Older Posts
Home
Subscribe to:
Posts (Atom)