aknow2

自分の興味のある事を連々と(プログラミング、モバイルアプリ、プログラミング教育)

Google Cloud Functionsでcorsを有効にする。

Cloud Functions特有なところも無く一般的なクロスドメインの話ですが、忘れないようにメモしときます。

環境

有効する方法

サーバーサイドでレスポンスのヘッダーに'Access-Control-Allow-Origin'と'Access-Control-Allow-Headers'の設定をします。

// 設定例
res.header('Access-Control-Allow-Origin', "*");
res.header('Access-Control-Allow-Headers', "Origin, X-Requested-With, Content-Type, Accept");

以下、簡単なチュートリアルを載せます。

チュートリアル

CloudFunctionの説明は省きます。

サーバーサイドですがCloud Functionを作成すると生成されるサンプルコードを使用します。 生成されるコードは以下です。

exports.helloWorld = (req, res) => {
  let message = req.query.message || req.body.message || 'Hello World!';
  res.status(200).send(message);
};

requestのクエリかボディにmessageという内容があれば、オウム返しするというシンプルな物です。 まずはこのままデプロイします。

次にクライアントサイドの例です。 ブラウザからFetchAPIで呼び出します。 送る内容は{"message": "hello gcf"}というJSON形式で送信します。
JSONで送るのでHeaderのContent-Typeをapplication/jsonにしています。
また、corsで送信するのでmode: 'cors'に設定します。 上手く実行されればChromeコンソール上に「hello gcf」と表示されるはず。

const headers = new Headers({
    "Content-Type": "application/json"
});
const body = JSON.stringify({message: 'gcf'});
const response = await fetch(
                                               'https://cloudfunctions/helloworld',
                                               {method: 'POST', mode:'cors', headers, body}
                                              );
const message = await response.text();
console.log(message);

この状態でクライアントサイドを実行して、Chromeの開発者ツールのコンソールを覗くと、以下のようなcorsのエラーが発生していると思います。 f:id:aknow2:20180911161455j:plain

サーバー側でAccess-Control-Allow-Originを付けろ!というエラーなので、サーバーサイドの修正を行います。エラーに出ている通りAccess-Control-Allow-Originを追加します。

exports.helloWorld = (req, res) => {
  let message = req.query.message || req.body.message || 'Hello World!';
  res.header('Access-Control-Allow-Origin', "*"); //追加した
  res.status(200).send(message);
};

この状態でデプロイ後、再びクライアント側を実行すると違うエラーが出てきます。
f:id:aknow2:20180911163651j:plain
次のエラーはサーバー側でAccess-Control-Allow-Headersを付けろ!と言う内容なので、またサーバーサイドを編集します。

exports.helloWorld = (req, res) => {
  let message = req.query.message || req.body.message || 'Hello World!';
  res.header('Access-Control-Allow-Origin', "*"); 
  res.header('Access-Control-Allow-Headers', "Origin, X-Requested-With, Content-Type, Accept");//さらに追加した
  res.status(200).send(message);
};

編集が終わったら再デプロイします。
この状態で実行するとChromeのコンソールにhello gcfと表示されるはずです!

【ASO・Android】自分のアプリがPlayストアどんな検索ワードで調べられているか知る方法

ASOが重要な事は言わずもがなですが、自分のPlayStoreのページにユーザがどの様に検索して辿り着いたか気になるところです。 実はplay consoleで自分のアプリのページがどんな検索キーワードでたどり着いたを知る事が出来ます。

どの様に検索されているか知ることで、アプリの紹介文やタイトルを見直す良い判断材料となるのではないでしょうか。

以下にその確認方法を紹介します。

【確認方法】

1.左部ドロワーの獲得レポートを開く
f:id:aknow2:20180910163652p:plain

2.獲得レポート下部のユーザー獲得チャネルの表にある「Playストア」→「検索」を開く
f:id:aknow2:20180910164146p:plain

3.開いたページの下部に検索されたキーワードの一覧が表示されています! f:id:aknow2:20180910164538p:plain

「デバッグ編」nodejs + TypeScriptでサーバーサイドを開発している時に、コードを編集したら自動リロードさせて、デバッグ。

nodejs + TypeScriptでサーバーサイドを開発している時に、コードを編集したら自動リロードさせる。 - aknow2
上記リンク先の記事の続きです。 先にこちらを御覧ください

前回の方法でTypescriptを編集した際に自動リロードする事が出来ました。
次にデバッグする方法です。

1.準備

chromeがあればOKです。

2.nodemonの設定変更

nodemonのexecの設定を以下の様に変更します。

// 前回の設定
{
    "watch": ["src"],   // 監視対象とするフォルダを指定
    "ext": "ts",    // 拡張子.tsを指定する
    "exec": "ts-node ./src/index.ts"  // nodemonを起動したら実行されるスクリプト
}

// 新しい設定
{
    "watch": ["src"], 
    "ext": "ts",  
    // 次を変更!
    "exec": "node --inspect -r ts-node/register ./src/index.ts"  
}

3.デバッグする

実行できたら、chromeを起動して chrome://inspect/#devicesにアクセスすれば
デバッグ出来るようになります!

これでTypescriptで楽に開発出来る環境が出来ました!

[PR]

play.google.com

React Router(v4)でcomponentクラス外から手動でページ遷移を行う。

まずReact Router v4 基本的なページ遷移の方法からです。
やり方は以下で出来ます。

// タグで指定する
class Hoge extends React.component {
  render (): JSX.Element {
    return <Link to='/my/link'>Link</Link>;
  }
}

// historyを利用する
class Hoge2 extends React.component {
   
   handleClick () {
        this.props.history.push('/my/link');
   }

   render (): JSX.Element {
    return <button onClick={this.handleClick}> Link </button>
  }
}

ただ、これらは<Router>の配下のComponent、又はwithRouter利用したComponent内でしか利用出来ません。
Componentの外からページ遷移をしたい場合、どの様にすれば良いか一例を紹介したいと思います。
(例はTypescriptで書いていますが、Javascriptでも殆ど変わらないと思います。

先ほどの例で this.props.history.push('my/link') とありましたが、
実際にページ遷移を実行しているのはhistoryオブジェクトです。
このhistoryオブジェクトをどうにかして、何処からでもアクセス出来るようにする
というのが今回とった方法です。

何処からでもアクセスさせるには
createBrowserHistoryという関数を利用して
historyオブジェクトを自前で生成しexportします。
これで何処からでもhistoryオブジェクトが参照出来るようになります。
今回はhistory.tsというファイルを作成して実装してます。

//history.ts
import createHistory from 'history/createBrowserHistory';
const History = createHistory();
export default History;

次にhistoryをReact Routerに設定します。
設定するには, <Router>のプロパティであるhistoryに指定すると出来ます。
下記はindex.tsがこのReactAppのルートファイルである場合の例です。

// index.ts
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import App from './App';
import './index.css';
import { Router, Route } from 'react-router-dom';
import history from './history'; // <- 先ほど作ったhistoryをimport

ReactDOM.render(
        <Router history={history}> // <-ここがポイント
          <Route path={'/'} component={App} />
        </Router>
  document.getElementById('root') as HTMLElement
);

下準備はこれでOKです。
ページ遷移を実行したい箇所でhistoryをインポートして pushメソッドを呼び出せばページ遷移が出来ます。

import history from './history.ts' 
class Linker {

    linkToMyLink() {
        history.push('/my/link');
    }

}

ただ、これをすると何処からでもページ遷移が出来てしまうので
設計時にどのレイヤーでページ遷移をすべきかちゃんと考えたいですね。 以上です。

【ホットリロード】nodejs + TypeScriptでサーバーサイドを開発している時に、コードを編集したら自動リロードさせる。

TypeScript+node.jsでサーバーサイドを開発してる時に、煩わしいこと

  1. TypeScriptをjavascriptコンパイルすること。
  2. ソースコードを編集したい場合、node.jsのプロセスを立ち上げなおす必要があること。

この二つの問題を問題を解決していきたいと思います。

追記: ボイラープレート作りました。設定面倒な人はこっちで試してみて下さい。
Node.js向けのTypescriptのボイラープレートを作った - aknow2

問題1 Typescirptからjavascriptへ変換

ts-nodeを利用。
ts-nodeとは、TypeScriptをnode上で実行してくれるREPLです。
そして、使い方も簡単です。

インストール方法
npm install -g ts-node
実行方法
ts-node ./src/index.ts  // 今回はsrcフォルダ下にあるindex.tsファイルを起動すると仮定

ts-nodeを利用するだけで、javascriptに変換する煩わしさが消えました。素晴らしい!
次!

問題2 ソースコード編集後のnode.js再起動

nodemonを利用する!
nodemonを使うとコード編集を自動で検知し、node.jsのプロセスも立ち上げ直してくれます。

インストール方法
npm install -g nodemon

これでターミナルでnodemon hoge.jsと実行すれば良いだけなのですが、、、
デフォルトの設定ではJavascriptのファイル(.js)しか検知してくれません。
TypeScriptの場合は少し手を入れる必要があります。

プロジェクトフォルダ直下にnodemon.jsonを作成し、
以下のように記述します。

{
    "watch": ["src"],   // 監視対象とするフォルダを指定
    "ext": "ts",    // 拡張子.tsを指定する
    "exec": "ts-node ./src/index.ts"  // nodemonを起動したら実行されるスクリプト
}

あとはターミナルでnodemonを実行するだけ

nodemon

これでTypeScriptからJavascriptへの変換、
node.jsの再起動の二つの煩わしさから解放されます!

お次はデバッグする方法です!
次の記事をご覧ください。

「デバッグ編」nodejs + TypeScriptでサーバーサイドを開発している時に、コードを編集したら自動リロードさせて、デバッグ。 - aknow2

参考

ts-node https://github.com/TypeStrong/ts-node

nodemon
https://github.com/remy/nodemon#config-files https://github.com/remy/nodemon/blob/master/doc/sample-nodemon.md

[PR]

https://play.google.com/store/apps/developer?id=Aknow2Gamesplay.google.com

必要なのはブラウザ(Chrome)だけ!コントラクト指向言語SolidityでEthereumのスマートコントラクトを実装してみる。

Ethereum、特にスマートコントラクトとかに興味があるけど
何か環境とか色々準備するのが面倒くさそうと思っている方

Ethereumにはテスト環境が公開されているので、
スマートコントラクトを実装して実行する事は
ブラウザだけでも出来てしまいます。

今回はブラウザ上でSolidityという
スマートコントラクトを実装するための言語を用いて
実際にスマートコントラクトを実装して
動かしてみる所までやってみます。

そもそも、スマートコントラクトって何?という方は
コチラを読んでみてください。

スマートコントラクトとは何か? Smart Contractの定義 | block-chain.jp

準備物

以下のものをインストールしてください。
1. Chromeブラウザ - download
2. Metamaskプラグイン - download

Metamaskの設定

  1. Metamaskがインストール出来るとアドレスバーの横に
    Metamaskのアイコンであるキツネが現れるのでクリックします。(下図)
    f:id:aknow2:20171219221923p:plain

  2. acceptを押します。
    f:id:aknow2:20171219222231p:plain

  3. 8文字以上のパスワードを入れます。
    f:id:aknow2:20171219222447p:plain

  4. アカウントを復旧させたい時に使う
    12ワードが表示されるので
    誰もアクセス出来ない、どこかに保存しましょう。 f:id:aknow2:20171220094403p:plain

  5. 次にテスト用のネットワークに接続しましょう。
    左上のMain Networkのドロップダウンを開いて
    Ropsten Test Networkを選択しましょう。
    f:id:aknow2:20171220094746p:plain

Mainネットワークは実際に運用されている
パブリックなEthereumのネットワークです。
ここで送金すると本当に送金されませす。
テストネットワークは3つ準備されており
違いは以下参照のことでお願いします。
Ethereum Testnet Selection

6. 最後にEther(通貨)をゲットしましょう。
スマートコントラクトを登録するにも呼び出す場合にも
EtherというEthereumで使われている通貨が必要となります。
テストネット上では無料で貰えるのでお金がかかる事はありません。

Buyボタンを押します
f:id:aknow2:20171220095707p:plain

Ropsten test faucetを押下。
f:id:aknow2:20171220095752p:plain

そうするとMetaMask Ether Faucetというサイトに飛ぶので
request 1ether from faucetを押すと1etherが貰えます。 f:id:aknow2:20171220095914p:plain

ただ、貰えるまでしばらく時間がかかるので放置しておきます。(1,2分?)
ブラウザ右上のMetamaskのアイコンからダイアログを開いて
所持金が1Ethになっていれば成功です。
f:id:aknow2:20171220100356p:plain

スマートコントラクトを実装しよう

さて、いよいよスマートコントラクトを実装します。
まず、IDEを準備しましょう。
準備すると言っても、Remixというブラウザ上で動作するIDEを使用するので
下記のURLにアクセスするだけです。
Remix - Solidity IDE

アクセスしたら、右側にあるRunのタブを選択して
一番上のEnvironmentをnjected web3に選択してください。(下図)
f:id:aknow2:20171221140315p:plain

ballot.solというサンプルのコントラクトが
表示されていますが、今回は使用しません。
左側の+ボタンから新しいコントラクトを生成しましょう。
名前は「FirstContract.sol」とします。
f:id:aknow2:20171221142806p:plain

今回、実装するコントラクトは以下になります。
作成したFirstContract.sol内にコピペしてください。

今回は単純にuint8という符号無しの数値型をセットして
ゲットするだけのコントラクトになります。
詳細はソースコード内のコメントを参照ください。

pragma solidity ^0.4.19;

//コントラクトの宣言
contract FirstContract { 

    //storedDataと呼ばれるの状態変数です。                                       
    //このstoredNumがブロックチェーンのストレージ上に
    //保存される値になります。
    uint8 storedNum = 1; 


    //setter 
    //変数storedNumを書き換えます
    // 関数の宣言方法は
    // function 関数名(引数) アクセス修飾子 戻り値
    // の順となります。
    function set(uint8 num) public{
        storedNum = num;
    }

    //getter
    // 変数storedNumを取得します
    // returns(uint8)で戻り値の型を指定しています。
    // viewと宣言されているのは、この関数が値値を参照するだけで
    // 書き換えを行うものではないという事を指しています。
    function get() public view returns(uint8){
        return storedNum;
    }
}

コピペ出来たら、いよいよテストネットにコントラクトを登録します。
Remix右側のRunタブにあるCreateボタンを押してください。
f:id:aknow2:20171221105812p:plain

すると下図のようなMetamaskのダイアログが開きます。
EthereumではGas Feeというetherの送金や
コントラクト実行のための手数料がかかります。
なので、コントラクトを登録するにも手数料がかかります。
Max Transaction Feeと書かれている部分が手数料の見積もりとなります。
ただし、Max Transaction Feeなので最大でこれだけ使うであろう
という見積もりの値段になっています。
実際に使われる費用は登録してみないとわかりません。

先ほどMetamaskで1ther分取得しているので
それを使ってコントラクトを登録します。
そのまま、Submitボタンを押してください。
f:id:aknow2:20171221110027p:plain

SubmitするとPendingになり登録中の状態になります。(下図) f:id:aknow2:20171221110407p:plain

しばらく、ブロックチェーン内に登録出来たら
下図の様にコントラクト名とアドレスが表示されると思います。
また、Metamaskを確認するとEtherが少し減っていることも確認しましょう。
Ethereumではコントラクトにもアドレスが与えられます。 f:id:aknow2:20171221163738p:plain

おめでとうございます。
これで今回のスマートコントラクトの実装と登録完了です。

今回、作成したgetとsetの関数がちゃんと動くか確かめて見ましょう。
まずはgetから、確認方法はRemix上から呼び出す事が出来るのでとっても簡単
先ほど表示されたコントラスト名の下にあるgetを押してみましょう。(下図)
初期値の1が返ってくるはずです。 f:id:aknow2:20171222103343p:plain

次にset関数
setの横がテキストボックスになっているので
"5"と入力して, setを押してみましょう。
注意!必ず値は" "ダブルクォーテーションで囲いましょう。(下図)
f:id:aknow2:20171222104907p:plain

setを押すとmetamaskのダイアログが表示されると思います。(下図)
コントラクトを呼び出した時に値を書き換える時は手数料がかかります。
先ほどのgetで値を参照するだけの場合は手数料は基本的にかかりません
大きいデータ量を引き出す時は手数料がかかるそうです。
そのまま、submitボタンを押して手数料を支払いましょう。
f:id:aknow2:20171222105529p:plain

しばらく時間を置いて、get関数を再度呼び出し
5が返ってこれば成功です。(下図)
f:id:aknow2:20171222105759p:plain

あまりにも簡単過ぎて
本当に動いているのか怪しくなります。
ブロックチェーン上でどの様に
動いているのか確認してみましょう。
コントラクトのアドレスをコピーしてください。(下図)
f:id:aknow2:20171222110031p:plain

下記のサイトにアクセスして右上のテキストボックスに
コピーしたアドレスを貼り付けて、Goを押してください
TESTNET Ropsten BlockChain Explorer and Search
f:id:aknow2:20171222110232p:plain

コントラクトの取引した情報が表示されます。(下図)
取引は全部で「コントラクトの生成」と「set関数の呼び出し」の
2つが表示されていると思います。
下図のToを見てみると最初に呼ばれた方がContract Creationになっていて
コントラクトが生成されたのが分かります。
また、表の一番右を見ると実際に支払った手数料が表示されます。
最後にsetした時のトランザクション情報を見て見ましょう
トランザクションの情報はTxHashから見る事が出来ます。

f:id:aknow2:20171222114805p:plain

色々乗ってますが、一番下のinput dataの右端が5になっているはずです。
これはset関数を呼び出した時に5をセットした事を表しています。
f:id:aknow2:20171222115219p:plain

今回は以上となります。
   じゃあ実際にwebアプリとか作って
スマートコントラクトを呼び出すためにはどうすれば?
等々はまた次回という事で、、、。

[PR]

【cordova・Android】プラグイン(ネイティブ側)のデバッグ

Cordovaで開発をしていると避けては通れないプラグイン達、、、
今回はプラグイン側のデバッグ方法を紹介します。

【環境】
・Windows10
Android Studio
・Nexus5X(実機・USBデバッグ有効済み)
今回はUSBで接続で接続した実機に対してデバッグする方法となります。

【事前条件】
・Cordovaプロジェクトを作成済み
プラグインを何個かインストール済みと仮定

【方法】
コマンドプロンプトで下記のコマンドでいつも通りデバッグビルドする

cordova build android

②またいつも通り、下記フォルダに生成されるAPKを実機に移して
インストール後に動作確認を行う。

{cordovaプロジェクトルート}\platforms\android\build\outputs\apk  

③AndroidStudioを起動する。
④AndroidStuidoで上部メニューバーからFile->Openで
下記のフォルダをAndroidのプロジェクトとして読み込む

 {cordovaプロジェクトルート}\platforms\android  

スマホをUSBでPCにつなげた状態でアプリを起動する。
⑥AndroidStudioからデバッグ対象のアプリにアタッチする(下図参照) f:id:aknow2:20171217132313p:plain
⑦下記のフォルダにネイティブ側のコードがあるので
適当にブレークポイントを張ってみてブレーク出来たら完成!

 {cordovaプロジェクトルート}\platforms\android\src

Cordovaでアプリを色々と作成中 play.google.com