接触確認アプリで「接触したとPUSH通知」→「アプリを開くと接触なし」になる問題
起きている現象
以下のような現象が起きてるようです
- 接触確認アプリ(COCOA)から 「
COVID-19 にさらされた可能性があります
」 というプッシュ通知が届く - 通知からアプリを開くと「
陽性者との接触は確認されませんでした
」という表示になっている - ( iOSでは通知は一度見ると消えるので、その後は通知は再度確認できなくなる )
Twitter上で、この現象が起きた方が複数確認できます
深夜に、”コロナにさらされた可能性があります”、とかいう恐ろしい通知が接触確認アプリから来て、見てみると、接触履歴無しと言う結果。可能性があるからアプリチェックしてみ、まー実際接触してないけどね、って事らしい。みんなこれビビらないのかな。#COCOA pic.twitter.com/vBkB0pFkPl
— 桑原優 KUWABARA Masaru (@KuwabaraMasaru) August 5, 2020
通知来たけどアプリはこの表示。何なの。。 pic.twitter.com/11hByrZW4b
— ヒロユキ (@miyazzy) July 21, 2020
必要な対応
現在の厚生労働省の公式見解
厚生労働省の「接触確認アプリ利用者向けQ&A」によると、この現象が起きた場合メールで問い合わせる必要があるとのことです。
以前は異なる見解だったことに注意
8月3日時点では現在と全く異なる見解で、通知がきてもアプリ上が接触者なしだと安心してくださいという見解だったようです。
アプリ立ち上げて、
— ぱしり@やっさいもっさい (@pasiri) August 2, 2020
「接触は確認されませんでした」
なら接触は検知されてないとの事なので、安心して出勤してる。https://t.co/UxlmyKPnoA pic.twitter.com/X4NZv4mXf9
上記の古い見解を見てメールを送ってない方がいれば、現在の見解にしたがってメールでの問い合わせをしたほうが良いと思われます。
接触を「一致したキー」から確認する方法
問い合わせた方によると「接触チェックの記録内で 一致したキーの数が1つ以上の場合は、陽性者との接触があったと判断してください」という回答をもらった方がいます。
続報
— zono (@me_zono) August 5, 2020
アプリQ&Aが変更され、この場合問い合わせろとの事→返信が来た
今日は時間外だったから明日電話。 pic.twitter.com/4w7H1eHrED
「一致したキー」の確認方法 (iOSの場合)
1 設定を開きます
2 設定画面の下のアプリ一覧から「接触確認アプリ」を選びます
3 「COVID-19接触ログ記録の設定」を押します
4 「接触チェックの記録」を押します
5 表示されている時刻を上から確認していきます。一番上のものから押します
- 全ての記録の「一致したキー」が0になっているかを確認します。
通知が来たような気がするが確認できない方で、1のものが存在すれば、その情報と合わせてメールで問い合わせを行ってみた方が良いと思われます。
記録が多すぎて確認が大変な場合
1「接触チェックの記録」画面の「接触チェックの記録を書き出す」を押します
2 コピーを選びます
3 コピーした内容をLINEでもメールでもメモアプリでも良いので、どこかに貼り付けてください
貼り付けた内容に「MatchCount」という文字が入ってる行の数字が全て0かを確認します。 通知が来たような気がするが確認できない方で、1のものが存在すれば、その情報と合わせてメールで問い合わせを行ってみた方が良いと思われます。
moshを導入しようとして凡ミスでハマった
moshを導入しようとして凡ミスしてたのでメモしておきます.
クライアント側に出ていたエラー
http://tukaikta.blog135.fc2.com/blog-entry-210.html
上記のエントリを参考にさせていただきながらサーバ側( sakuraのVPS )とクライアント側( mac )の設定を行いました。 無事設定完了して、クライアント側のmacからmoshを起動しようとすると下記のようなエラーがでて起動できませんでした。
mosh: Nothing received from server on UDP port 60001.
Firewallの確認
サーバ側のFirewallはiptablesに以下のように設定していたのでポートは開いているような気がしていました。
-A RH-Firewall-1-INPUT -m state --state NEW -m udp -p udp --dport 60000:61000 -j ACCEPT
そこで、実際に通信が行われているか確認するためにサーバ側でtcpdumpを実行して確認してみました。
tcpdump host (クライアント側のhostname) and not (SSHのポート) # sshのpacketが邪魔なのでフィルタリングしておく 22:53:19.477223 IP (クライアント側のhostname).60950 > (サーバ側のhostname).60001: UDP, length 71 22:53:19.477271 IP (サーバ側のhostname) > (クライアント側のhostname): ICMP host (サーバ側のhostname) unreachable - admin prohibited, length 107
あぁ。。。と思いiptablesの設定を見直してみると icmp-host-profibitedの設定がmoshのポート設定の上にきてしまっていました。。
iptablesは上からフィルタが適応されているので、これでは当然動かないですね。凡ミス。
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited .... # 先にicmp-host-prohibitedの設定が適応されてしまているので動かない -A RH-Firewall-1-INPUT -m state --state NEW -m udp -p udp --dport 60000:61000 -j ACCEPT
以下のように順番を逆にすると無事動いた。
-A RH-Firewall-1-INPUT -m state --state NEW -m udp -p udp --dport 60000:61000 -j ACCEPT ... -A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
凡ミスでタイムロスしないように気をつけます。
それにしてもmosh、快適ですね・・・!
回線がe-mobileしかない貧民なので、感動しました。
■hoge
コメント欄でJSが利用できますので、どうぞご利用ください^^
# 酷いコメントが多いのでやめました^^
cakePHP内でPEAR Services_Amazonのキャッシュ機能を使おうとするとエラー
気がついたら1年ぶり以上のCake関係の記事。
さて、最近またCakePHPを使ってWEBアプリを組んでいるので久々に更新します。
最近、Product Advertising APIと名前が変わったAmazonのAPI。
これを使うのに便利なライブラリとしてPEAR Services_Amazonがあります。
このライブラリを使用すると、通信結果結果を配列で取得、Amazonから取得したデータのキャッシュの実装などなどが簡単に行えます。
が、CakePHP内部で、このライブラリのキャッシュ関係の部分が動かずハマってしまったので、かつ同じようにハマる人がいそうなのでメモしておきます。
発生したエラーについて
CakePHPの、あるmodelの中で、次のようなコードを書きました
<?php require_once("Services/Amazon.php"); $amazon = new Services_Amazon($amazon_access_key, $amazon_secret_key, $amazon_associate_key); $amazon->setLocale("jp"); $amazon->setCache('file', array('cache_dir' => '/path/to/cache/dir/')); ?>
すると以下のようなエラーが発生
Fatal error: Call to undefined method Cache::get() in /usr/share/php/Services/Amazon.php on line 1361
エラーが起こっているServices/Amazon.phpの処理を見て、原因特定
1361行目のクラスの_sendRequestメソッド内の_cacheというプロパティからgetメソッドを実行しようとしているところでエラーが起こっています。
<?php $cache = $this->_cache->get($cache_id); ?>
・$this->_cacheの初期化
ということで、この_cacheプロパティに、どのようなインスタンスが設定されるのかをチェック。
397行目から、始まるsetCacheメソッド内で初期化されています。
<?php 397 function setCache($container = 'file', $container_options = array()) 398 { 399 if(!class_exists('Cache')){ 400 @include_once 'Cache.php'; 401 } 402 403 @$cache = new Cache($container, $container_options); 404 405 if (is_object($cache)) { 406 $this->_cache = $cache; 407 } else { 408 $this->_cache = null; 409 return PEAR::raiseError('Cache init failed'); 410 } 411 412 return true; 413 }
エラー処理も、きちんとしてるし問題なさそうです。
今回、発生したエラーはCache::getというメソッドが存在していねぇよっというエラーなので、$cacheのメソッド一覧を確認してみましょう。
406行目の下に次の行を追加してみます
<?php 407 print_r( get_class_methods($this->_cache) ); >?
以下が結果です。
<?php Array ( [0] => getInstance [1] => __loadEngine [2] => config [3] => engine [4] => set [5] => gc [6] => write [7] => read --略--- [20] => cakeError [21] => _persist [22] => _savePersistent [23] => __openPersistent ) >?
あ、あれ、このメソッドどこかで見たことあるぞ。。。っていうか配列の20個目,cakeとかいう文字が。。。PEARのライブラリなのに。。。
つまり、CakePHP内でもCacheという名前のクラスがあって、それがPEARのCacheクラスと競合していました。
Services/Amazon.phpはPEAR Cacheを使用したいのに、CakePHPのCacheクラスのインスタンスが生成されてしまっています。
解決方法(暫定
ということで解決方法です。
今回とった方法は、あんまりよくないかもしれないけど、PEARのライブラリを書き換えてしまいます。
1.Cache.phpをコピーしてCache_PEAR.phpを作成
まず、クラス名が被っているのがまずいのでPEAR::Cacheのクラス名を変更します。
直でCache.phpを書き換えてもいいのだけど、一応コピーをとって、そっちを書き換える方針で。
2.Cache_PEAR.phpの次の2箇所(クラス名とコンストラクタ部分)を変更
- 66行目
- 129行目
3.Services/Amazon.phpでCacheインスタンスの代入部分を変更
- 変更前
<?php 399 if(!class_exists('Cache')){ 400 @include_once 'Cache.php'; 401 } 403 @$cache = new Cache($container, $container_options); >?
- 変更後
<?php 399 if(!class_exists('Cache_PEAR')){ 400 @include_once 'Cache_PEAR.php'; 401 } 403 @$cache = new Cache_PEAR($container, $container_options); >?
結果
無事、Services_Amazonのキャッシュ部分が動きました。
cakePHPのfindAllで柔軟なJOINを行う
やりたいこと
あるコントローラでfindを実行する際に,一箇所でのみ特定のテーブルとJOINをしたり,状況によってJOIN設定を変更する方法について考える.
もっとも、そこまで特殊で数箇所でしか使用しないリレーションの場合,直接SQLを書いてしまったほうがラクだったりもする。
今回、findをJOINするのは,他のコンポーネントとの兼ね合い。特にPaginationコンポーネントを利用する場合に、直接SQLを書くとコンポーネントを利用したページング設定に手間がかかりそうだから。
$model->beforeFindを設定することで、そのmodelに関するfindのSQLを発行するときのJOINの設定などを行うことができるが、これはmodel自体の設定のため、findを使用している箇所全てに適用される。
(詳細は→CakePHP findAll で INNER JOIN する方法 | Sun Limited Mt. )
ということで今回、もう少し柔軟にJOINを発行する方法について考えてみる。
環境
php5 + cakephp 1.1.17.5612
cakePHP自体のコード変更する場合
- ./cake/libs/model/model_php5.phpを以下のように変更
<?php //最終引数に$joinsを追加 function findAll($conditions = null, $fields = null, $order = null, $limit = null, $page = 1, $recursive = null,$joins = null) { //--------略----------------- $queryData = array('conditions' => $conditions, 'fields' => $fields, 'joins' => $joins, //変更部分 'limit' => $limit, 'offset' => $offset, 'order' => $order ); //--------略----------------- return $return; } ?>
- コントローラー内での使い方は以下のようになる
<?php $joins[] = array( "type" => "INNER", "alias" => "", "table" => INNER JOIN するテーブル, "conditions" => INNER JOIN の ONに指定する条件, ); $findAll($conditions , $fields, $order, $limit, $page, $recursive,$joins); ?>
beforeFindを用いる場合(cakePHP本体のコード変更しない場合)
- cakePHP本体のコードが変更できない場合は$model->beforeFindを定義することになる
- しかしbeforeFindはモデル自体に適応されるため、コントローラーすべてのfindに適用される
- find毎に設定を変更するためにプロパティを追加する方法を考えてみる
./app/model/モデル名.phpを編集
- プロパティにjoinSettings、メソッドにbeforeFindを以下のように追加
<?php var $joinSettings = array(); function beforeFind(&$queryData){ $queryData["joins"] = $this->joinSettings; return true; }
コントローラー側での使い方
- JOINが必要ないときは通常にfindを使用
- JOINが必要なときはfindの前に以下のように記述
<?php $this->モデル名->joinSettings[] = array( 'type' => 'LEFT', 'alias' => '', 'table' => 'テーブル名', 'conditions' => 条件, ); ?>
- これで特定の箇所だけ特定のJOINを実行できるはず