knaka Tech-Blog

AI, IoT, DIYエレクトロニクス, データサイエンスについて投稿予定です。

Laravel 5.8 + firebase Cloud Messaging で、web push通知対応の チャット機能の作成

前のLaravel 関係で
firebase Cloud Messaging, Notification API 等で web push通知対応の
チャット機能の作成となります。

参考のコード

github.com

画面

・通知
 メンバーからの、通知ポップアップと。着信音が出力されます

f:id:knaka0209:20200119171018p:plain

・チャットの画面
dbに、メッセージを保存しておき。
過去の投稿も表示可能です。

f:id:knaka0209:20200119171046p:plain

・チャット一覧
 ほぼCRUDですが、チャット作成、参加が可能
f:id:knaka0209:20200119171612p:plain

実装など

・ルーティング 、画面や API

Route::get('/chats/add_member', 'ChatsController@add_member')->name('chats.add_member');
Route::resource('chats', 'ChatsController');
//
Auth::routes();
//
Route::get('/home', 'HomeController@index')->name('home');


/**************************************
 * API
 **************************************/
Route::prefix('api')->group(function(){
    Route::get('/apichats/get_post', 'ApiChatsController@get_post');
    Route::post('/apichats/update_token', 'ApiChatsController@update_token');
    Route::post('/apichats/update_post', 'ApiChatsController@update_post');
});

・コントローラ
ChatsController.php
https://github.com/kuc-arc-f/lara58a_6chat/blob/master/app/Http/Controllers/ChatsController.php

・Blade
チャット画面: chats/show.blade.php
https://github.com/kuc-arc-f/lara58a_6chat/blob/master/resources/views/chats/show.blade.php

・FCM(firebase Cloud Messaging) の設定や、
 鍵等の取得は、前のブログと同様です

参考のページ

Cloud Messaging の設定など
knaka0209.hatenablog.com

firebase Cloud Messaging + Notification APIで、Web push通知

firebase Cloud Messaging を使用して、
ブラウザにpush通知の内容となります。

環境

chrome 79 以降
webサーバ

ドメインは、localhost でも動作しました

参考のpush画面

・受信メッセージが、デスクトップに表示できました
win10ですが

f:id:knaka0209:20200115171250p:plain

準備など

firebase (firebase.google.com )
にログインし、作成したプロジェクトを開く

・Project Pverview >設定(歯車アイコン)>プロジェクトの設定

・Cloud Messaging タブ 開きます。

・サーバーキー
 トークンを、コピーしておきます。

・送信者 ID (送信時に使用)
  IDを、コピー
・鍵ペア(公開鍵)
 ウエブ設定> ウエブプッシュ証明書 、のあたり
 初回は、鍵の作成で。良かったと思います。

 鍵ペアを、コピーしておきます。

・Notification API で通知ですが、
 テストする場合。
 ブラウザの通知、許可を設定しておく必要があります。

参考のコード

github.com

実装など

ドメイン直下に、
 firebase-messaging-sw.js, manifest.json
を配置

・firebase-messaging-sw.js
 に、送信者ID を、設定

firebase.initializeApp({
  'messagingSenderId': 'YOUR-SENDER-ID'
 下記、messagingSenderId の部分
});

・受信、送信画面
https://github.com/kuc-arc-f/fcm_sample1/blob/master/test/fcm_recv2.html

・firebase 設定で、送信者ID を、設定
 下記、messagingSenderId の部分

・公開鍵、
 下記 YOUR_PUBLIC_VAPID_KEY_HERE の部分 設定

firebase.initializeApp({
   'messagingSenderId': 'YOUR-SENDER-ID'
 });
//FCM
const messaging = firebase.messaging();
messaging.usePublicVapidKey('<YOUR_PUBLIC_VAPID_KEY_HERE>');

・サーバーキー の設定
上記の、トークン追加

const FCM_SERVER_KEY = "YOUR-SERVER-KEY";

・token取得
 送信先トークンを、画面起動時に取得

    messaging.getToken().then((currentToken) => {
        if (currentToken) {
            sendTokenToServer(currentToken);
            IID_TOKEN = currentToken;
            textInstanceIdToken.value = IID_TOKEN;
//        console.log(currentToken);
        } else {
            // Show permission request.
            alert("ブラウザ通知を許可に設定下さい。メッセージを送受信できません");
            console.log('No Instance ID token available. Request permission to generate one.');
            // Show permission UI.
            updateUIForPushPermissionRequired();
            setTokenSentToServer(false);
        }
    }).catch((err) => {
        console.log('An error occurred while retrieving token. ', err);
        setTokenSentToServer(false);
    });

受信

    messaging.onMessage((payload) => {
//        console.log('Message received. ', payload);
        var notify = payload.notification;
        console.log(notify.title );
    });

送信

fetchで、送信例です
・FCM_SERVER_KEY は、上記のサーバーキー 
toは、上記で取得した。送信先 token

function test_send(){
//console.log(IID_TOKEN.length );
    var send_title = elem_title.value;
    var send_body = elem_body.value;

    if(IID_TOKEN.length < 1){ return; }
    var key = FCM_SERVER_KEY;
    var to = IID_TOKEN;
    var notification = {
        'title': send_title,
        'body': send_body,
        'icon': 'firebase-logo.png',
        'click_action': 'http://localhost'
    };

    fetch('https://fcm.googleapis.com/fcm/send', {
    'method': 'POST',
    'headers': {
        'Authorization': 'key=' + key,
        'Content-Type': 'application/json'
    },
    'body': JSON.stringify({
        'notification': notification,
        'to': to
        })
    }).then(function(response) {
//        console.log(response);
    }).catch(function(error) {
        console.error(error);
    })
};


・送信すると、firebase (firebase Cloud Messaging) 経由で
 メッセージが送信され、上記の画面のような
 push通知画面が。表示できました。

Laravel 5.8で、CSVインポート機能

前のLaravel 関係で
CSVアップロードで、DB更新となります。

参考のコード

github.com

実装など

・コントローラ
計測値等の、管理ですが

https://github.com/kuc-arc-f/lara58a_5mdat/blob/master/app/Http/Controllers/MdatsController.php

    public function csv_import(Request $request){
        $user_id = Auth::id();
        // CSVファイルをサーバーに保存
        $temporary_csv_file = $request->file('csv_file')->store('csv');
        $fp = fopen(storage_path('app/') . $temporary_csv_file, 'r');
        // 一行目(ヘッダ)読み込み
        $headers = fgetcsv($fp);

        $column_names = [];
        // CSVヘッダ確認
        foreach ($headers as $header) {
            $result = Mdat::retrieveTestColumnsByValue($header, 'SJIS-win');
            if ($result === null) {
                fclose($fp);
                Storage::delete($temporary_csv_file);
                session()->flash('flash_message', '登録に失敗しました。CSVファイルのフォーマットが正しいことを確認してださい。');
                return redirect()->route('mdats.index');
            }
            $column_names[] = $result;
        }
        $csv_items = [];
        while ($row = fgetcsv($fp)) {
            mb_convert_variables('UTF-8', 'SJIS-win', $row);
            $csv_items[] = $row;
        }
        fclose($fp);
//debug_dump( $csv_items );
        $errors = $this->validator($csv_items );
        if(count($errors) > 0 ){
            return redirect()->back()->withErrors($errors)->withInput();
        }

        foreach ($csv_items as $row) {
            $date  =$row[0];
            if(!empty($date)){
                $mdat = Mdat::where('user_id', $user_id )
                ->where('date', $date )->first();
                if(empty($mdat) ){
                    $mdat = new Mdat();
                    $data["date"] = $row[0];
                    $data["hnum"] = $row[1];
                    $data["lnum"] = $row[2];
                    $data["user_id"] = $user_id;
                    $mdat->fill($data );
                    $mdat->save();
                }else{
                    $mdatArray = $mdat->toArray();
                    $mdat = Mdat::find($mdatArray["id"]);
                    $data["date"] = $row[0];
                    $data["hnum"] = $row[1];
                    $data["lnum"] = $row[2];
                    $mdat->fill($data );
                    $mdat->save();
                }    
            }
        }
        return redirect()->route('mdats.index');
    }

画面

f:id:knaka0209:20200104180311p:plain

csv出力

    public function csv_get(){
        $user_id = Auth::id();
        $dt = new Carbon(self::getYm_firstday());
        $now_month= $dt->format('Y-m');
        $startDt = $dt->format('Y-m-d');
        $endDt = $dt->endOfMonth()->format('Y-m-d');
//dd($startDt);
//exit                
        $mdats = Mdat::orderBy('date', 'asc')
        ->where("user_id", $user_id )
        ->whereBetween("date", [$startDt, $endDt ])
        ->get(['date', 'hnum', 'lnum'] )->toArray();
//dd($mdats );
        $csvHeader = ['date', 'Height' , 'Low'];
        array_unshift($mdats, $csvHeader);   
        $stream = fopen('php://temp', 'r+b');
        foreach ($mdats as $mdat ) {
            fputcsv($stream, $mdat );
        }
        rewind($stream);
        $csv = str_replace(PHP_EOL, "\r\n", stream_get_contents($stream));
        $csv = mb_convert_encoding($csv, 'SJIS-win', 'UTF-8');
        return response($csv )
            ->withHeaders([
                'Content-Type' => 'text/csv',
                'Content-Disposition' => 'attachment; filename="mdat.csv"',
            ]);

    }

Seeder

追加データのseederを追加しました。
https://github.com/kuc-arc-f/lara58a_5mdat/blob/master/database/seeds/MdatTableSeeder.php

php  artisan db:seed --class=MdatTableSeeder

Seederクラスのエラーが出る場合、 composerを再実行すると。エラーが回避できました
php composer.phar dump-autoload

ゲーミングマウス 500円、レビュー編

index:

概要

ダイソー様の、500円(税別)で購入できた 
ゲーミングマウスについての記事となります。

・作業PC用の amazonで購入した300円低価格マウス
 が古くなったので、買い替え品を探したところ
 有線USB マウスが、100均様に。販売されていたので購入してみました。

感想

低下価格ですが、良さそうなマウスと思います。

画像

・梱包はそれなりに、安っぽいイメージは無かったようです。
f:id:knaka0209:20191229185001j:plain

・LEDで、マウス光るんですよね
 少し暗い照明で。撮影です
f:id:knaka0209:20191229185025j:plain

その他

・右指の当たる部分は、すべりにくい素材のようで
 押しやすい気がします。
・側面は、普通のプラ素材で、安っぽく見えました
・側面にもボタンが有り、機能はありそうで
よく把握してないのですが。。
 ゲーム用途でなくても、PC作業のマウスとしても使えそうです

update

Update : 2020/01/10
2週間程で、左側のボタンが押しても。反応しない事が
多くなりました。。
個体差は、ありそうですが。耐久性の面でNGかもしれません

Laravel 5.8で、予定表の機能追加 #php #Laravel

index:

概要:

前の Laravel 5.8 関係で、
Carbon を使用して、予定管理の機能追加となります。

環境

php7.3
Laravel 5.8
mysql

参考のコード

github.com

画面

・top
f:id:knaka0209:20200101144836p:plain

・追加
f:id:knaka0209:20191228203908p:plain

migrate

https://github.com/kuc-arc-f/lara58a_4plan/blob/master/database/migrations/2019_12_24_164755_create_plans_table.php

    public function up()
    {
        Schema::create('plans', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->bigInteger('user_id')->nullable(false);
            $table->date('date')->nullable()->comment('予定の日付');
            $table->text('content')->nullable()->comment('内容');;
            $table->timestamps();
            $table->softDeletes();
        });
    }

Update

・2020/01/01
TOP/月の移動方法を、INPUT type=month を追加し。
 指定月に、移動できるように修正。しました

Raspberry Pi+ docker に、Laravel 5.8を設置する。

index:

概要:

前の Laravel 5.8 関係で、
raspbery pi+ docker環境 で、Laravel 5.8追加する内容となります

・使用する面で、docker-compose 起動が遅かったり。
 いまいちな面が、ありましたので。参考程度となります

・composer 実行も、作業時間が1時間以上は経過してたと思いますので
 注意が必要です。

環境

raspbery pi 2
php7.3
Laravel 5.8
mysql
docker
docker-compose

参考の docker 設定

github.com

参考のページ

knaka0209.hatenablog.com

追加の手順

インフラ側は、前回の docker-compose
で、起動したコンテナ使います

・Laravel 5 の追加
コンテナで、作業 の開始

docker-compose exec app /bin/bash

・Laravel の追加

php composer.phar create-project --prefer-dist laravel/laravel myblog "5.8.*"
php composer.phar require laravelcollective/html "5.8.*"

・ここで、composer で、メモリ関係エラーが出る場合、
一旦、コンテナを停止して。docker run で起動しました

メモリ領域、256Mだと失敗しましたので。512Mに変更

docker run -m 512m -it -v /home/pi/work/docker/docker_raspi_lara58:/var/www/html docker_raspi_lara58_app /bin/bash

・再度、create-projectで。インストール完了
http://設置したIP/ で、laravel 起動できました。

f:id:knaka0209:20191223135342p:plain

Laravel 設定

前の、ubuntu版と同じ .envですが。DB_HOST=db 
で、接続できました

.env

DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=root

migrate 実行

php artisan migrate

create_usersで、エラーが出ましたが。表は作成されていたので
 2014_10_12_000000_create_users_table.php を削除して、他のmigrate実行してみましたが。
 問題なく、モデルも使用できました

===========================
root@e4c2159cf43b:/var/www/html/myblog/database/migrations# rm -r 2014_10_12_000000_create_users_table.php
root@e4c2159cf43b:/var/www/html/myblog/database/migrations# cd ../../
root@e4c2159cf43b:/var/www/html/myblog# php artisan migrate
Migrating: 2019_12_01_081526_create_tasks_table
Migrated: 2019_12_01_081526_create_tasks_table (0.08 seconds)
Migrating: 2019_12_12_020837_create_books_table
Migrated: 2019_12_12_020837_create_books_table (1.7 seconds)
Migrating: 2019_12_14_082209_create_depts_table
Migrated: 2019_12_14_082209_create_depts_table (0.1 seconds)
Migrating: 2019_12_14_082310_create_members_table
Migrated: 2019_12_14_082310_create_members_table (0.06 seconds)
Migrating: 2019_12_17_001753_create_todos_table
Migrated: 2019_12_17_001753_create_todos_table (1.61 seconds)

まとめ

CRUD等の画面を開くと。やや重く。
上記の、docker-compose up -d 起動も遅いのですが。
連続稼働で、ほぼ停止しない場合は、
低コスト小型PCで、省電力で。良い面もありそうですね

Raspberry Pi に docker環境を設置する

index:

概要:

前の Laravel 5.8 関係で、
raspbery piに docker環境 追加するメモとなります
構成は、php7.3 ,mysql , nginx

・下記の、docker-compose 追加が作業時間が多めでした。。
 参考までに。数時間かかったので 要注意です。

環境

raspbery pi 2
php7.3
Laravel 5.8
mysql
docker
docker-compose

version

pi@raspberrypi:~/tmp $ uname -a
Linux raspberrypi 4.14.98-v7+ #1200 SMP Tue Feb 12 20:27:48 GMT 2019 armv7l GNU/Linux

pi@raspberrypi:~/tmp $ cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 9 (stretch)"
NAME="Raspbian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"

pi@raspberrypi:~/tmp $ docker --version
Docker version 19.03.5, build 633a0ea

docker-compose 追加

ビルドは、1時間以上 だった気がします。

git clone https://github.com/docker/compose.git
cd compose
git checkout 1.25.0

./script/build/linux

・バイナリが、ビルドされるようです

$ cd dist
$ ./docker-compose-Linux-armv7l version

/usr/local/bin にコピーする場合、

$ sudo cp docker-compose-Linux-armv7l /usr/local/bin/docker-compose
$ cd /usr/local/bin
$ sudo chown root:root docker-compose
$ sudo chmod 755 docker-compose

参考のdocker 設定

github.com

参考の docker-compose.yml

https://github.com/kuc-arc-f/docker_raspi_lara58/blob/master/docker-compose.yml

version: '3'

services:
 web:
    build: ./docker-nginx
    ports:
        - 80:80
    depends_on:
        - app
    volumes:
        - ./:/var/www/html
        - ./docker-nginx/default.conf:/etc/nginx/conf.d/default.conf
    links:
        - app
 app:
    build: ./docker-php
    depends_on:
        - db
    links:
        - db
    volumes:
        - ./:/var/www/html
 db:
    image: hypriot/rpi-mysql
    ports:
      - 3306:3306
    environment:
      MYSQL_ROOT_PASSWORD: root         #
      MYSQL_DATABASE: laravel         #
      MYSQL_USER: db_user           #ユーザ名
      MYSQL_PASSWORD: password   #ユーザ用パスワード

コンテナ起動

docker-compose up -d

・こちらも、以上30分以上は。起動処理が継続してました。注意です

・nginx がタイムアウトになる場合が、有りましたが。
再度、起動すると。エラーが消えました

============================
ERROR: for docker_raspi_lara58_web_1 UnixHTTPConnectionPool(host='localhost', port=None): Read timed out. (read timeout=60)

ERROR: for web UnixHTTPConnectionPool(host='localhost', port=None): Read timed out. (read timeout=60)
ERROR: An HTTP request took too long to complete. Retry with --verbose to obtain debug information.
If you encounter this issue regularly because of slow network conditions, consider setting COMPOSE_HTTP_TIMEOUT to a higher value (current value: 60).

============================

参考ページです

knaka0209.hatenablog.com