AWS – Cognitoでemailを変更した場合、認証してなくても古いメアドはログインできない

Cogitoを使った認証でユーザが登録後に、メアドを変更する際に
入力ミスで違うメアド入れちゃったけど、アプリからはログアウトしちゃった
という状況はどうなるのか?

javascriptでテストしてみる。

まずユーザを登録する。

var attributeList = [];
attributeList.push(new AWSCognito.CognitoIdentityServiceProvider.CognitoUserAttribute({
	Name: 'name',
	Value: $('#name').val()
}));
attributeList.push(new AWSCognito.CognitoIdentityServiceProvider.CognitoUserAttribute({
	Name: 'email',
	Value: $('#email').val()
}));
userPool.signUp($('#email').val(), $('#password').val(), attributeList, null, function(err, result) {
	if (err) {
		console.log(err);
		return;
	}
	cognitoUser = result.user;
	console.log('Username:' + cognitoUser.getUsername());
});

登録後、認証コードが送られてくるので、認証コードを登録してメールアドレスを認証済みにする。


Cognitoで見ると、メールアドレスは認証済みになっているので
そのユーザでログインして、メールアドレスの変更を行う。


認証コードが新しいメールアドレスに送信されるが
それを認証せずに、古い情報でログインしようとすると


認証エラーが発生してログインできない。

Cognito上ではメアドは変更されていて、認証済みが取り消されている。
これに対応するにはdynamoで管理するか、cognitoに追加の属性を持たせて、認証や変更トリガーでmail属性を認証後にアップデートするようにしました。

GoogleのGoogleDrive乗っ取られた?エロ画像を置かれた

GoogleDriveは使ってないんですが
たまたまGmailのメールから添付Drive経由で開いて、削除しようと一覧を開いたらエロ画像が置かれていて、x****@gmail.comと共有になっていて、半年以上前からになっていて、Googleに削除されなかったのが救い。。

何かアプリをインストールした時なのか、わからないけどドライブへの許可をしてたみたいで、API経由でアップロードなのかシェアされていたみたい。

使わないつもりのサービスでもたまにチェックしないと、不意にアカウント停止の対象になるかもしれない。

GADInvalidInitializationException-GoogleMobileAdsアップデートしたら動かなくなった

GADInvalidInitializationExceptionが発生

GoogleMobileAdsをアップデートしたら、iOSアプリがクラッシュするようになってしまった。


2019-03-29 17:20:39.153251+0900 test.app[9165:102709] *** Terminating app due to uncaught exception 'GADInvalidInitializationException', reason: 'The Google Mobile Ads SDK was initialized incorrectly. Google AdMob publishers should follow instructions here: https://googlemobileadssdk.page.link/admob-ios-update-plist to include the AppMeasurement framework, set the -ObjC linker flag, and set GADApplicationIdentifier with a valid App ID. Google Ad Manager publishers should follow instructions here: https://googlemobileadssdk.page.link/ad-manager-ios-update-plist'
*** First throw call stack:

GADInvalidInitializationExceptionの原因

いままでAppDelegateでGADMobileAds.configure( APPID )してましたがこれがとうとうダメになったようです。

‘configure(withApplicationID:)’ is deprecated: Use [GADMobileAds.sharedInstance startWithCompletionHandler:]


 GADMobileAds.configure(withApplicationID: 

今後はInfo.plistにGADApplicationIdentifierを追加するらしいです。


GADApplicationIdentifier
ca-app-pub-123~????????

Androidはちょっと前からmanifest.xmlに追加が必要になっていたので同じ感じ。
Googleが解析しやすいようにするのかな?

carthageでpkluz/PKHUDがBuild Failed – バージョン指定を間違えてビルドエラー


$ cat Cartfile
github "pkluz/PKHUD" ~> 4.0

$ carthage update --platform iOS PKHUD
*** Building scheme "PKHUD" in PKHUD.xcodeproj
Build Failed
	Task failed with exit code 65:
	/usr/bin/xcrun xcodebuild -project /Users/dp/dev/Xcode/test.app/Carthage/Checkouts/PKHUD/PKHUD.xcodeproj -scheme PKHUD -configuration Release -derivedDataPath /Users/dp/Library/Caches/org.carthage.CarthageKit/DerivedData/10.2_10E125/PKHUD/4.2.3 -sdk iphoneos ONLY_ACTIVE_ARCH=NO CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY= CARTHAGE=YES archive -archivePath /var/folders/bv/0637g83s7bz_l040pkghmt380000gn/T/PKHUD SKIP_INSTALL=YES GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=NO CLANG_ENABLE_CODE_COVERAGE=NO STRIP_INSTALLED_PRODUCT=NO (launched in /Users/dp/dev/Xcode/test.app/Carthage/Checkouts/PKHUD)

This usually indicates that project itself failed to compile. Please check the xcodebuild log for more details: /var/folders/bv/0637g83s7bz_l040pkghmt380000gn/T/carthage-xcodebuild.15y1aS.log

Build Failed , Task failed with exit code 65

ログを確認します。


cat /var/folders/bv/0637g83s7bz_l040pkghmt380000gn/T/carthage-xcodebuild.15y1aS.log

note: Planning build
note: Constructing build description
Build system information
error: SWIFT_VERSION '3.0' is unsupported, supported versions are: 4.0, 4.2, 5.0. (in target 'PKHUD')

Build system information
error: SWIFT_VERSION '3.0' is unsupported, supported versions are: 4.0, 4.2, 5.0. (in target 'PKHUD')

** ARCHIVE FAILED **

バージョン指定間違ってた。。


$ cat Cartfile
- github "pkluz/PKHUD" ~> 4.0
+ github "pkluz/PKHUD" ~> 5.0

https://github.com/pkluz/PKHUD

Xcode10.2 (10E125)にしたらcarthageでIncompatible Swift version

carthageはバイナリが準備されていればダウンロードしてビルド短縮しますが
importしたバイナリがXcodeのアップデートで4から5になってしまったので
buildした環境と変わってしまったのでエラーが出てしまいました。


Skipped installing FontAwesome.swift.framework binary due to the error:
	"Incompatible Swift version - framework was built with 4.2.1 (swiftlang-1000.11.42 clang-1000.11.45.1) and the local version is 5.0 (swiftlang-1001.0.69.5 clang-1001.0.46.3)."

version0.20からはSwiftのバージョンが異なる場合ビルドしてくれるそうなので
Carthageをバージョンアップしました。


brew upgrade carthage

version0.20からはSwiftのバージョンが違ったので「Falling back to building from the source」を勝手に実行してくれました。


** Downloading FontAwesome.swift.framework binary at "Dynamic Type"
***  Skipped installing FontAwesome.swift.framework binary due to the error:
	"Incompatible Swift version - framework was built with 4.2.1 (swiftlang-1000.11.42 clang-1000.11.45.1) and the local version is 5.0 (swiftlang-1001.0.69.5 clang-1001.0.46.3)."

    Falling back to building from the source

SlimフレームワークでLaravelで有名なEloquentのEvent(self::creating,updating,savingイベント)が動かなかったのを解決できた

EloquentはLaravelでなくても便利なのでORMとしてCodeigniterやSlimで利用してますが
Eloquentのモデルが設定したイベントが呼ばれないので調べてみました。

エラーにはならず、普通にORMとして機能するんですけど、イベントが如何せんよばれない。。


class User extends Model {
public static function boot(){
	parent::boot();
	self::creating(function ($q) {
log出力とかしたい。
	});
	self::updating(function ($q) {
log出力とかしたいのに、イベントが呼ばれない。。
	});
}

$user = User::find(1);
$user->last_login_at = time();
$user->save();

最初slim eloquent event not working,slim eloquent event not callなどで
ググったけど、SlimでEloquentとなるとModelの基本しか見つからないので
vendorの中をちゃんと読むことにしました。

Illuminate\Database\Eloquent\Model.phpを見ると
トレイトにHasEventsってぽいやつがいる。
そして中でイベントが設定されていれば、Dispatcher読んでる。



Model.php

namespace Illuminate\Database\Eloquent;

abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializable, QueueableEntity, UrlRoutable
{
    use Concerns\HasAttributes,
        Concerns\HasEvents,
        Concerns\HasGlobalScopes,
        Concerns\HasRelationships,
        Concerns\HasTimestamps,
        Concerns\HidesAttributes,
        Concerns\GuardsAttributes,
        ForwardsCalls;


HasEvents.php
namespace Illuminate\Database\Eloquent\Concerns;

use Illuminate\Contracts\Events\Dispatcher;

trait HasEvents
{
    /**
     * The event map for the model.
     *
     * Allows for object-based events for native Eloquent events.
     *
     * @var array
     */
    protected $dispatchesEvents = [];
省略
    /**
     * Get the observable event names.
     *
     * @return array
     */
    public function getObservableEvents()
    {
        return array_merge(
            [
                'retrieved', 'creating', 'created', 'updating', 'updated',
                'saving', 'saved', 'restoring', 'restored',
                'deleting', 'deleted', 'forceDeleted',
            ],
            $this->observables
        );
    }
省略
    protected function registerObserver($class)
    {
        $className = $this->resolveObserverClassName($class);

        // When registering a model observer, we will spin through the possible events
        // and determine if this observer has that method. If it does, we will hook
        // it into the model's event system, making it convenient to watch these.
        foreach ($this->getObservableEvents() as $event) {
            if (method_exists($class, $event)) {
                static::registerModelEvent($event, $className.'@'.$event);
            }
        }
    }

イベントディスパッチャーはIlluminate\Contracts\Events\Dispatcherか。
と思いディレクトリを探すと無い。
そこで気づきました。。イベント設定してもDispatcher無いじゃん。
EventってEloquentが持ってるのかよければ依存で持ってきてると思ったけど。。。違うよね。。

今回はSlimを利用していて、下記のようにDBを読んでいます。


// DIC configuration
$container = $app->getContainer();

$container['db'] = function( $c ) {
	$capsule = new \Illuminate\Database\Capsule\Manager;
	$capsule->addConnection( $c['settings']['db'] );
	$capsule->getConnection()->enableQueryLog();
	$capsule->setAsGlobal();
	$capsule->bootEloquent();
	return $capsule;
};

composer.jsonはこんな感じ


"require": {
	"slim/slim": "^3.12",
	"monolog/monolog": "^1.24",
	"danielstjules/stringy": "^3.1",
	"respect/validation": "^1.1",
	"illuminate/database": "^5.5"
},

さっそくイベントライブラリを追加します。


composer require illuminate/container
composer require illuminate/events

そして、コンテナに入れてるDBにも設定を追加します。
最初間違って、setAsGlobalの後にsetEventDispatcherして動かなくて悩みました。。


use Illuminate\Events\Dispatcher as Dispatcher;
use Illuminate\Container\Container as Container;

// DIC configuration
$container = $app->getContainer();

$container['db'] = function( $c ) {
	$capsule = new \Illuminate\Database\Capsule\Manager;
	$capsule->addConnection( $c['settings']['db'] );
	$capsule->setEventDispatcher( new Dispatcher( new Container ) );
	$capsule->getConnection()->enableQueryLog();
	$capsule->setAsGlobal();
	$capsule->bootEloquent();
	return $capsule;
};

これでSlimフレームワークでもEloquentのModelイベントが動くようになりました。

Slim Frameworkでsettingsに追加した設定値が$c->get(‘settings’)でnull

SlimでTwitterAPIやSessionの設定をsettingsに追加しましたが

コンテナに追加する際に、設定値がNullになっていしまう。


$container['twitterOAuth'] = function ($c) {
    $settings = $c->get('settings')['twitter'];
    var_dump( $c->get('settings') );
    exit;

Null

エラーも特に出てないので、Slimがどうやってsettingsを読んでいるか見てみた。

slim/slim/Slim/Collection.php


他はgetterなどなんで、フィルターはない。
public function __construct(array $items = [])
    {
        $this->replace($items);
    }

slim/slim/Slim/Container.php


settingsが空ならEmptyでCollection作るけど
valuesにはあるけど、userSettingsにはない。
public function __construct(array $values = [])
{
       parent::__construct($values);
var_dump( $values ); ある

       $userSettings = isset($values['settings']) ? $values['settings'] : [];

var_dump( $userSettings );  ない

    $this->registerDefaultServices($userSettings);
}
private function registerDefaultServices($userSettings)
{
    $defaultSettings = $this->defaultSettings;

    /**
     * This service MUST return an array or an
     * instance of \ArrayAccess.
     *
     * @return array|\ArrayAccess
     */
    $this['settings'] = function () use ($userSettings, $defaultSettings) {
        return new Collection(array_merge($defaultSettings, $userSettings));
    };

    $defaultProvider = new DefaultServicesProvider();
    $defaultProvider->register($this);
}

なんてことはなく、settings.phpのsettingsの閉じが意図してなかっただけ。。
return ‘settings’ , ‘session’ , ‘twitter’;
になってただけだった。。

settings.php


// Monolog settings
    'logger' => [
        'name' => 'App',
        'path' => __DIR__ . '/logs/app.log',
        'level' => \Monolog\Logger::DEBUG,
        ],
    ], // 多いい。。。。

Android App Bundle (Androidアプリバンドル) -aabからapkを作成してサイズ削減量をチェックしてみる

mobile-ffmpegを組み込んだAndroidアプリをリリースしたけどサイズが大きい。。
full-gplからminにするだけで20MB以上は削減できるけど
それでもAPKファイルは35MB近くある。。

Android App Bundleでリソースファイルだけでも小さくできないか試してみました。

アプリバンドルの作成

Android StudioのビルドからAPKではなく、バンドルを選んで出力するだけ。

アプリバンドルから端末向けのAPK生成

bundletoolをダウンロード

https://github.com/google/bundletool
Bundletool is a tool to manipulate Android App Bundles.
The Android App Bundle is a new format for publishing Android apps in app distribution stores such as Google Play.

”–connected-device”でadbで接続中の端末に向けたApkができるらしい。


 java -jar bundletool-all-0.9.0.jar build-apks \
 --bundle=/ path to /app.aab \
 --output=/ path to /myapp.apks \
 --ks=~/.android/debug.keystore \
 --ks-pass=pass:android \
 --ks-key-alias=androiddebugkey \
 --key-pass=pass:android \
 --connected-device

自分の環境では35MB->30MBだったので効果はあった。

既存のAPK配信アプリをバンドルへ移行

upload_cerとdeployment_certは表示されてるので、ローカルのkeystoreとPEPKで紐づけるのか
PEPKツール(Play Encrypt Private Key)が必要らしいけどダウンロードボタンどこ?。。
あとでにします。