プレゼントの内容は旅行です
長いの複数の記事です
行き先は、横浜の白楽と鎌倉です
白楽はもともと私が住んでいた街です
その街に行きました
満喫の棚に並んでいて、おっぱいに負けて選んだ
1・親なしの14歳が悪魔を召喚して願ったのがお姉ちゃんがほしい
24ページより引用
2・悪魔も人間や姉になる事を楽しんでいる
35ページより引用
3・おっぱいがデカすぎ!!
29ページより引用
飯田ぽち。さん
「通常攻撃が全体攻撃で二回攻撃のお母さんは好きですか」の
イラストを書いている人
通常攻撃が全体攻撃で二回攻撃のお母さんは好きですか? (富士見ファンタジア文庫)
コミケで同人のエロ系を書いていたっぽい
どの絵も髪の毛が綺麗!!
女性作家ならではですね
画像はTwitterより引用しています
前回、サムネイルをつくるfunctionと翻訳するfunctionを作ったが
2つのfunctionを1つのindex.jsに書くという通常の開発ではありえない事をした
node.jsの初心者なんでトライアンドエラーで分割をした
いけていない所があります
try { admin.initializeApp(functions.config().firebase); } catch (err) { //console.error('Firebase initialization error', err.stack) }
トライ・アンド・キャッチしている所です
別の所で定義するとエラーでうごかず、
trycathcにしないとデプロイができない
デプロイのエラー
Error: The default Firebase app already exists. This means you called initializeApp() more than once without providing an app name as the second argument. In most cases you only need to call initializeApp() once. But if you do want to initialize multiple apps, pass a second argument to initializeApp() to give each app a unique name. at FirebaseAppError.FirebaseError [as constructor] (/tmp/fbfn_11222Qg6NpvXGscFd/node_modules/firebase-admin/lib/utils/error.js:25:28) at new FirebaseAppError (/tmp/fbfn_11222Qg6NpvXGscFd/node_modules/firebase-admin/lib/utils/error.js:70:23) at FirebaseNamespaceInternals.initializeApp (/tmp/fbfn_11222Qg6NpvXGscFd/node_modules/firebase-admin/lib/firebase-namespace.js:38:23) at FirebaseNamespace.initializeApp (/tmp/fbfn_11222Qg6NpvXGscFd/node_modules/firebase-admin/lib/firebase-namespace.js:237:30) at Object.<anonymous> (/tmp/fbfn_11222Qg6NpvXGscFd/generateThumbnail/index.js:6:8) at Module._compile (module.js:571:32) at Object.Module._extensions..js (module.js:580:10) at Module.load (module.js:488:32) at tryModuleLoad (module.js:447:12) at Function.Module._load (module.js:439:3) at Module.require (module.js:498:17) at require (internal/module.js:20:19) at Object.<anonymous> (/tmp/fbfn_11222Qg6NpvXGscFd/index.js:9:29) at Module._compile (module.js:571:32) at Object.Module._extensions..js (module.js:580:10) at Module.load (module.js:488:32) at tryModuleLoad (module.js:447:12) at Function.Module._load (module.js:439:3) at Module.require (module.js:498:17) at require (internal/module.js:20:19) at /usr/lib/node_modules/firebase-tools/lib/triggerParser.js:18:11 at Object.<anonymous> (/usr/lib/node_modules/firebase-tools/lib/triggerParser.js:32:3)
う~ん・・・
trycatchは最終手段に近いのいずれ治したい
イベントがすべてのフォルダで取得しているみたいなので
そこも特定のフォルダのみのイベントにしたい
module.exports = functions.storage.object().onChange(event => {
今はファイルパスをチェックして処理を終了させている
(間違えているきがする・・・)
const filePath = event.data.name; // filePath uploads以外はサムネイルを作らない if (!filePath.startsWith('uploads')) { console.log('This is not "uploads/" path.'); console.log(filePath); return; }
node.jsの経験がないから、本当に時間がかかる
楽しいからいいですけど〜♪
Google Android Firebase: Learning the Basics (English Edition)
定期的にfunctionsを実行したかったが
サンプルをみた所ないらしい
github.com
しかも外部のサービスを記載していた
https://www.setcronjob.com/
https://cron-job.org/
https://www.easycron.com/
https://zapier.com/zapbook/webhook/
T_T
google先生っぽくないな~
無料でやるならGoogle Apps Scriptでおこなうが楽かも
www.sakana.tech
ちなみにAWS Lambdaにある
docs.aws.amazon.com
対抗しているなら作ってくださいよ
モンストで物語シリーズのコラボがありました
怒られるかもしれませんが
歴代のコラボの中で酷いコラボだったと思う
物語シリーズが好きな私はコンプしたいのですが
コラボガチャがない
10連ガチャのおまけで戦場ヶ原ひだぎ(ガハラさん)と忍野忍がでる仕様でした
youtuberじゃない無課金ユーザーの私は
10連ガチャなんて1ヶ月に1,2回ぐらいしかひけません
それもおまけが絶対にでる仕様ではない
ガチャの動画をみていると
30連に1体でる感じでした
10連は約3,000円なので
18,000円を突っ込まないといけない仕様だった
奇跡的に10連で忍野忍がでたが
戦場ヶ原ひだぎは諦めた
運極は1キャラあたりクエストを40~50回ぐらいやればいけます
(対応キャラ次第)
今回の酷い所は
八九寺真宵の所です
クリアボーナスで64体、メダル引き換えで35体入手すれば運極を作ることができる。
メダルは計70万枚必要なため、メダル集めが苦でなければ運極を目指そう。
【モンスト】化物語シリーズコラボのガチャ当たり一覧とおすすめ運極 - GameWith
より引用
メダルが70万枚です
ぼっちの自分が1クエストでもらえるコインは2000枚です
つまり約350回ぐらいのクエストクリアが必要になる
8/8(火)12:00〜9/2(土)11:59なので
1日あたり13回以上クリアしないといけないのです
なでこスネイクが250回、つばさキャットが100回ぐらいやった
最後の方はなでこスネイクは画面をみないでも打てるなった
好きじゃないと周回できないよ
つばさキャットの曲をここまで聞かされるとは思わなかった
せめて、メダルブースターのイベントがほしかった
幽遊白書のコラボは敵が強すぎという酷いパターンがあったが
これほど時間がかかるコラボはなかったと思う
ちなみにgamewithナウシカさんはお金で解決していた。羨ましい
10連ガチャで15,000コインが手に入る
それを120連していた。すげー
前回でファイルアップができるようになった
その画像をもとに色々できるようなのでまずはサムネイル画像作成をやってみました
firebaseのstorageにファイルがアップされたら
changeイベントを取得してfirebaseのfunctionsを起動して
サムネイル画像を作成する
npmのパッケージの設定
/functions/package.json
{ "name": "functions", "description": "Cloud Functions for Firebase", "dependencies": { "firebase-admin": "^4.2.1", "firebase-functions": "^0.5.7", "request": "^2.81.0", "lodash": "^4.17.4", "request-promise": "^4.2.1", "@google-cloud/storage": "^0.4.0", "child-process-promise": "^2.2.0", "mkdirp": "^0.5.1", "mkdirp-promise": "^4.0.0" }, "private": true }
記載が完了したら
npm installのコマンドでインストールする
/functions/index.js
const mkdirp = require('mkdirp-promise'); // Include a Service Account Key to use a Signed URL //const gcs = require('@google-cloud/storage')({keyFilename: 'service-account-credentials.json'}); var gcs = require('@google-cloud/storage')({ projectId: 'angular-study-chat', keyFilename: './service-account-credentials.json' }); const spawn = require('child-process-promise').spawn; const path = require('path'); const os = require('os'); const fs = require('fs'); // Max height and width of the thumbnail in pixels. const THUMB_MAX_HEIGHT = 200; const THUMB_MAX_WIDTH = 200; // Thumbnail prefix added to file names. const THUMB_PREFIX = 'thumb_';
//thumbnail exports.generateThumbnail = functions.storage.object().onChange(event => { // File and directory paths. const filePath = event.data.name; const fileDir = path.dirname(filePath); const fileName = path.basename(filePath); const thumbFilePath = path.normalize(path.join(fileDir, `${THUMB_PREFIX}${fileName}`)); const tempLocalFile = path.join(os.tmpdir(), filePath); const tempLocalDir = path.dirname(tempLocalFile); const tempLocalThumbFile = path.join(os.tmpdir(), thumbFilePath); // console.log('filePath'); // console.log(filePath); // Exit if this is triggered on a file that is not an image. if (!event.data.contentType.startsWith('image/')) { console.log('This is not an image.'); return; } // Exit if the image is already a thumbnail. if (fileName.startsWith(THUMB_PREFIX)) { console.log('Already a Thumbnail.'); return; } // Exit if this is a move or deletion event. if (event.data.resourceState === 'not_exists') { console.log('This is a deletion event.'); return; } // Cloud Storage files. const bucket = gcs.bucket(event.data.bucket); const file = bucket.file(filePath); const thumbFile = bucket.file(thumbFilePath); // Create the temp directory where the storage file will be downloaded. return mkdirp(tempLocalDir).then(() => { // Download file from bucket. return file.download({destination: tempLocalFile}); }).then(() => { console.log('The file has been downloaded to', tempLocalFile); // Generate a thumbnail using ImageMagick. return spawn('convert', [tempLocalFile, '-thumbnail', `${THUMB_MAX_WIDTH}x${THUMB_MAX_HEIGHT}>`, tempLocalThumbFile]); }).then(() => { console.log('Thumbnail created at', tempLocalThumbFile); // Uploading the Thumbnail. return bucket.upload(tempLocalThumbFile, {destination: thumbFilePath}); }).then(() => { console.log('Thumbnail uploaded to Storage at', thumbFilePath); // Once the image has been uploaded delete the local files to free up disk space. fs.unlinkSync(tempLocalFile); fs.unlinkSync(tempLocalThumbFile); // Get the Signed URLs for the thumbnail and original image. const config = { action: 'read', expires: '03-01-2500' }; return Promise.all([ thumbFile.getSignedUrl(config), file.getSignedUrl(config) ]); }).then(results => { console.log('Got Signed URLs.'); const thumbResult = results[0]; const originalResult = results[1]; const thumbFileUrl = thumbResult[0]; const fileUrl = originalResult[0]; // Add the URLs to the Database return admin.database().ref('images').push({path: fileUrl, thumbnail: thumbFileUrl}); }).then(() => console.log('Thumbnail URLs saved to database.')); });
記載が終わったら
firebase deploy --only functions
でデプロイするが
Error: ENOENT: no such file or directory, open 'service-account-credentials.json' at Error (native)
あれ・・・
サンプルに書いてありました
なのでservice-account-credentials.jsonをつくることにしました
firebaseのコンソール画面で
①歯車のマークをクリックする
②ユーザーと権限をクリックする
①サービスアカウント
②サービスアカウントを作成をクリックする
①サービスアカウント名を適当にいれる
②新しい秘密鍵の提供をクリック
③JSONをクリックする
④G Suiteドメイン全体の委任を有効にするをクリック
⑤役割を選択する
⑥ストレージのストレージ管理者
この作成したjsonファイルをservice-account-credentials.jsonにリネームして
/functions/の配下においてもう1度デプロイする
firebase deploy --only functions
ちなみにサービスアカウントをミスをすると以下のエラーがでた
ApiError: Forbidden at new util.ApiError (/user_code/node_modules/@google-cloud/storage/node_modules/@google-cloud/common/src/util.js:107:10) at Object.parseHttpRespMessage (/user_code/node_modules/@google-cloud/storage/node_modules/@google-cloud/common/src/util.js:149:33) at Object.handleResp (/user_code/node_modules/@google-cloud/storage/node_modules/@google-cloud/common/src/util.js:124:18) at Duplexify.<anonymous> (/user_code/node_modules/@google-cloud/storage/src/file.js:711:21) at emitOne (events.js:96:13) at Duplexify.emit (events.js:188:7) at emitOne (events.js:96:13) at DestroyableTransform.emit (events.js:188:7) at emitOne (events.js:96:13) at Request.emit (events.js:188:7) at Request.<anonymous> (/user_code/node_modules/@google-cloud/storage/node_modules/request/request.js:1108:14) at emitOne (events.js:101:20) at Request.emit (events.js:188:7) at IncomingMessage.<anonymous> (/user_code/node_modules/@google-cloud/storage/node_modules/request/request.js:1091:12) at IncomingMessage.g (events.js:292:16) at emitNone (events.js:91:20) at IncomingMessage.emit (events.js:185:7) at endReadableNT (_stream_readable.js:974:12) at _combinedTickCallback (internal/process/next_tick.js:80:11) at process._tickDomainCallback (internal/process/next_tick.js:128:9)
https://github.com/GoogleCloudPlatform/google-cloud-node/issues/1388
このエラーがでたらサービスアカウントにミスがあります
今回も
https://github.com/codediodeio/angular-firestarter/tree/master/src/app/uploads
を参考にしています
サンプルとして既にあるのですが
ファイルアップベースにfirebase functionを動かしたりしたいので
1から作って理解したいと思いやっています