react-native-chart-kitのbakgroundcolorが設定できない件

chartConfig={{
     backgroundColor: '#1cc910',
     backgroundGradientFrom: '#eff3ff',
     backgroundGradientTo: '#efefef',
     decimalPlaces: 2,
     color: (opacity = 1) => `rgba(0, 0, 0, ${opacity})`,
     style: {
          borderRadius: 16,
            },
}}

このうちbackgroundに関する部分が動かない。辛い。

解決方法

react-native-svgのバージョンを下げる

    "react-native-svg": "^10.0.0"

どうやら、react-native-svgのurlが使えないというバグのようです。
どのバージョンから動くかちょっと定かではないですが、とりあえず10.0.0にしたら動きました。

https://github.com/indiespirit/react-native-chart-kit/issues/315

ただそれでもGradationは動きませんでした。とりあえずこのまま使います

Posted By :
Comment :0

expoのNotifications、Push通知について読んでみる

expo,React-nativeでアプリを作っているのでせっかくだからプッシュ通知をやってみたいと思いドキュメントを読んでいる。

(ちなみにプログラミング教えてくれている友人からは初めてでそれはやめとけと言われてます)

https://docs.expo.io/versions/latest/sdk/notifications/

ExpoのドキュメントのNotifications

Push通知には2種類あって
上段Push notificationsというのがサーバーを介して送られてくるもので、Local notificationsというのはアプリが起動していない時でもローカル内で完結する形で通知を送れるというものだそうです。

2種類あること自体初めて知ったのですが、Localの方はリマインダーのような用途で使われているみたいです。久しぶりにアプリを開いたりすると急にまた開くことを促すような通知がくるのはこれだったんですね。

  • 一定時間経過したことを知らせる
  • カートに商品が入ってることを通知する(カゴ落ち)
  • 久々に開いた顧客に対しクーポンを発行する

こういったリテンション施策で使うのが良さそうです。

今回は通常のサーバーを経由するpush notificationsの方をみます。

https://docs.expo.io/guides/push-notifications/

ここに概念図がありますが

Expoの場合は、一度expoの方で受けてくれて、android,iosのプッシュ通知を送るシステムに振り分けてくれるみたいです。

(なんとなくGoogleとかAppleからなんか送られるんだろうなあぐらいのことしか知りませんでした)

このExpo backendいくらかかるんだろうと思って調べてみると

https://forums.expo.io/t/is-there-any-limit-for-sending-push-notification/2265

よっぽど大規模ならともかく、基本は無料で使わせてくれるみたいです。

プログラミングを始めていろんなライブラリが無料で提供されてるのは本当にすごいなあとしみじみ感じます。

あと、当たり前かもしれませんがExpo ejectできなくなりますね。これは結構悩ましい問題みたいです。


サンプルコードはここで動かしてみれます

https://snack.expo.io/?platform=android&name=Push%20Notifications&sdkVersion=37.0.0&dependencies=expo-constants%2Cexpo-permissions&sourceUrl=https%3A%2F%2Fdocs.expo.io%2Fstatic%2Fexamples%2Fv37.0.0%2Fpushnotifications.js

最初の対応表にあったようにエミュレーターでは動きません。

import React from 'react';
import { Text, View, Button, Vibration, Platform } from 'react-native';
import { Notifications } from 'expo';
import * as Permissions from 'expo-permissions';
import Constants from 'expo-constants';

export default class AppContainer extends React.Component {
  state = {
    expoPushToken: '',
    notification: {},
  };

  registerForPushNotificationsAsync = async () => {
    if (Constants.isDevice) {
      const { status: existingStatus } = await Permissions.getAsync(Permissions.NOTIFICATIONS);
      let finalStatus = existingStatus;
      if (existingStatus !== 'granted') {
        const { status } = await Permissions.askAsync(Permissions.NOTIFICATIONS);
        finalStatus = status;
      }
      if (finalStatus !== 'granted') {
        alert('Failed to get push token for push notification!');
        return;
      }
      token = await Notifications.getExpoPushTokenAsync();
      console.log(token);
      this.setState({ expoPushToken: token });
    } else {
      alert('Must use physical device for Push Notifications');
    }

    if (Platform.OS === 'android') {
      Notifications.createChannelAndroidAsync('default', {
        name: 'default',
        sound: true,
        priority: 'max',
        vibrate: [0, 250, 250, 250],
      });
    }
  };

  componentDidMount() {
    this.registerForPushNotificationsAsync();

    // Handle notifications that are received or selected while the app
    // is open. If the app was closed and then opened by tapping the
    // notification (rather than just tapping the app icon to open it),
    // this function will fire on the next tick after the app starts
    // with the notification data.
    this._notificationSubscription = Notifications.addListener(this._handleNotification);
  }

  _handleNotification = notification => {
    Vibration.vibrate();
    console.log(notification);
    this.setState({ notification: notification });
  };

  // Can use this function below, OR use Expo's Push Notification Tool-> https://expo.io/dashboard/notifications
  sendPushNotification = async () => {
    const message = {
      to: this.state.expoPushToken,
      sound: 'default',
      title: 'Original Title',
      body: 'And here is the body!',
      data: { data: 'goes here' },
      _displayInForeground: true,
    };
    const response = await fetch('https://exp.host/--/api/v2/push/send', {
      method: 'POST',
      headers: {
        Accept: 'application/json',
        'Accept-encoding': 'gzip, deflate',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(message),
    });
  };

  render() {
    return (
      <View
        style={{
          flex: 1,
          alignItems: 'center',
          justifyContent: 'space-around',
        }}>
        <View style={{ alignItems: 'center', justifyContent: 'center' }}>
          <Text>Origin: {this.state.notification.origin}</Text>
          <Text>Data: {JSON.stringify(this.state.notification.data)}</Text>
        </View>
        <Button title={'Press to Send Notification'} onPress={() => this.sendPushNotification()} />
      </View>
    );
  }
}

/*  TO GET PUSH RECEIPTS, RUN THE FOLLOWING COMMAND IN TERMINAL, WITH THE RECEIPTID SHOWN IN THE CONSOLE LOGS

    curl -H "Content-Type: application/json" -X POST "https://exp.host/--/api/v2/push/getReceipts" -d '{
      "ids": ["YOUR RECEIPTID STRING HERE"]
      }'
*/

さて、、、上から見ていきます。

    if (Constants.isDevice) {
      const { status: existingStatus } = await Permissions.getAsync(Permissions.NOTIFICATIONS);
      let finalStatus = existingStatus;
      if (existingStatus !== 'granted') {
        const { status } = await Permissions.askAsync(Permissions.NOTIFICATIONS);
        finalStatus = status;
      }
      if (finalStatus !== 'granted') {
        alert('Failed to get push token for push notification!');
        return;
      }
      token = await Notifications.getExpoPushTokenAsync();
      console.log(token);
      this.setState({ expoPushToken: token });
    } else {
      alert('Must use physical device for Push Notifications');
    }

ここでデバイストークンと呼ばれるどの端末かを識別するためのIDをとって流みたいです。途中に

const { status } = await Permissions.askAsync(Permissions.NOTIFICATIONS);

ここでよくアプリをインストールした時に出てくる通知を許可しますか?というのを聞いてます。

https://docs.expo.io/versions/latest/sdk/permissions/

Permissionsはosのバージョンによって結構変更ありそうですね。

    if (Platform.OS === 'android') {
      Notifications.createChannelAndroidAsync('default', {
        name: 'default',
        sound: true,
        priority: 'max',
        vibrate: [0, 250, 250, 250],
      });

Androidではいくつかプッシュ通知に関するオプションを指定する必要があり、それを渡しています。

https://developer.android.com/training/notify-user/channels


  componentDidMount() {
    this.registerForPushNotificationsAsync();

    // Handle notifications that are received or selected while the app
    // is open. If the app was closed and then opened by tapping the
    // notification (rather than just tapping the app icon to open it),
    // this function will fire on the next tick after the app starts
    // with the notification data.
    this._notificationSubscription = Notifications.addListener(this._handleNotification);
  }

書いてある通り、アプリが開かれている時に通知が来た場合や、通知をタップした際にどのような動作をするかを記述します。

  // Can use this function below, OR use Expo's Push Notification Tool-> https://expo.io/dashboard/notifications
  sendPushNotification = async () => {
    const message = {
      to: this.state.expoPushToken,
      sound: 'default',
      title: 'Original Title',
      body: 'And here is the body!',
      data: { data: 'goes here' },
      _displayInForeground: true,
    };
    const response = await fetch('https://exp.host/--/api/v2/push/send', {
      method: 'POST',
      headers: {
        Accept: 'application/json',
        'Accept-encoding': 'gzip, deflate',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(message),
    });
  };

ここで実際のプッシュ通知のfunctionを作ってます。この内容を変えていくとプッシュ通知の内容を変えていくことができます。多分まだ理解しきれてないです。。。

なんとなくで、値をいじって色々やってみます。

  render() {
    return (
      <View
        style={{
          flex: 1,
          alignItems: 'center',
          justifyContent: 'space-around',
        }}>
        <View style={{ alignItems: 'center', justifyContent: 'center' }}>
          <Text>Origin: {this.state.notification.origin}</Text>
          <Text>Data: {JSON.stringify(this.state.notification.data)}</Text>
        </View>
        <Button title={'Press to Send Notification'} onPress={() => this.sendPushNotification()} />
      </View>
    );
  }

表示す部分です。ボタンが押された時にsendPushNotification()を送るようになってます。

送られてきたPush通知をタップしてみると、内容をちゃんと受け取れていることが確認できます。

Posted By :
Comment :0

react-native-elementsでFormInputが使えない件

react-native,プログラミング初心者故の凡ミスです。

Formを作ってみるとエラー
Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it’s defined in, or you might have mixed up default and named imports.

Formを作ろうとreact native forminputと検索すると。。。

こんな感じで出てきて一番上をクリックするとreact-native-elementsのものが出てくるのですが

なんとver0.19.1とずいぶん前のものが出てきます。

IntelliJの自動追加でpackage.jsonに入れていたので

    "react-native-elements": "latest"

となっていたためエラー。最新版はInputとなっていてFormなくなってます。

https://react-native-elements.github.io/react-native-elements/docs/input.html

Posted By :
Comment :0

[未解決]AWS AppSync + Apollo clientで”currentObservable.query.getCurrentResult is not a function”

AWSAppSyncClient, Apollo & React Native,Expoで動かしてみるとエラーが

TypeError: this.currentObservable.query.getCurrentResult is not a function

調べてみるとどうやらaws-appsyncが古いバージョンのapollo-clientを呼び出してしまうらしい。

ただ、amplify pullした直後は普通に動いていて、触っているうちに動かなくなってしまったので一体なんなのだろうという感じ。。。

https://stackoverflow.com/questions/60804372/proper-way-to-setup-awsappsyncclient-apollo-react

このエラーで検索するとだいたい

https://github.com/apollographql/react-apollo/issues/3148

https://github.com/apollographql/react-apollo/issues/3368

"resolutions": {
    "apollo-client": "2.6.3"
 }

これを入れればいいと書いてあるけれども、実際は解決せずそれでも結局古いapollo-clientを参照してしまうらしいので解決しない。

やっとこさ見つけたのがこの記事

https://medium.com/@guillac124/create-your-custom-apollo-client-for-aws-appsync-to-use-hooks-2d5cbce29db5

https://hubarifront.hatenablog.com/entry/2020/04/27/113850

結局のところaws-appsyncを使わないという手段をとっている。
自分はここで面倒になったので動いたところにrollbackしてしまった。

aws-appsyncを使う方はgitignoreからappsync関連を外しておいた方が良さそうです。

Posted By :
Comment :0

ad

Posted By :
Comment :0

高い安い以外の金銭的尺度と金銭に対する感受性について

例えばアートを買うとする。アートを買うということは、ほぼほぼ作者に対する投票行動であり、応援であり、次をお願いするような感じだ。
しかし普通アートは変われない。投資的な目的出会ったりとか、あまり本質的な理由じゃない買われ方をする。

しかも、なんだかとても非合理的なものに思える。アートを買うということは、どことなく僕の中では批判めいたものを感じる。
その価格は非合理的なもので、どうしてその価格になったのかは明らかに作者の一存で、その価値があるかどうかは虚像に見えるからだ。
単なるボッタクリだなんて言わないけれど、違和感を感じているような気がする。

しかしながら、どうしてそういう風に感じてしまうのか。そういう教育を受けてきたからという一言で片付けたくはない。

突き詰めていけばどのようなブランドであっても、結果的にはそのブランドに対する投票行動であって、そのブランドがつけた値段は虚像である。
例えばもちろん、ルイビトンのバッグは品質が良く、そもそも手間がかかっていて丁寧な仕事がされていることは間違えない。
しかしながら、それでもあの価格にはならない。合理的な値段ではないはずだ。合理的な値段は多分それの半分ぐらいだろう。

ブランドの宣伝広告費を含めれば全体の利益率としては合理的な範疇に収まるのだろうが、その宣伝広告は一般的な企業からすればとても合理的ではないものに見える。

でも売れている
ということは、買う人間は非合理的で愚かな人間であるということになるのだろうか。
ここを自問自答していると、どうやら僕はお金持ち、特に高いもので非合理的とお思われる値段をつけるものを購買しているそうに一定の愚かさを感じているようだ。

結局のところ、エモいという落合陽一に対してもそうだけど、その一定の合理性のなさに対して斜に構えて否定的な態度を取っているのだろう。なぜなら
なんだかわからないけどそこには行けない という悔しさがあるからだ。
また、自分の感性にかけるなんてできないという一種の自身のなさもあり、さらに誰かに教えを乞うているわけではないので、そういう不定形な、抽象的なものは
人脈で担保されるものだから(これ自体が斜に構えてる)その方向には行けないとも思っているのだろう。
また、そこには生まれ持った天才が行けるものでそうじゃない人が努力で巻き返すことはできない。そんなのずるい!みたいな子供みたいな感情もある気がする。

総じてまとめると、いまだに、試験の点数を取った人がえらいみたいな価値観から抜けかけてるけど、抜けきってないというところなのだろう。
ものの購買にフォーカスすると、浪費してはならないという考えから、安いと感じるものを買わなくてはならないという考えにつながり、そこから高いと感じる
ものを買う人を非合理的であると非難しているのだろう。
例えば10億のアートを買うときにも、安いと感じたから買いました。みたいな感じにこのまま行くとなるのだろう。ものすごいひねくれてる上に、それこそ非合理的存在だ。

何かの価値がお金の尺度に落としこまれる瞬間、その落とし込まれた結果の評価は高いか安いかどちらかということはないはずだ。もっと多様な、豊かな評価軸があるはずなのだ。
しかし文章を書いていて高い安い以外の表現がパッとかけない。それぐらい僕はお金の尺度上での感受性が貧相なのだ。

これでは繰り返しになるが、アートを買うときも安いと感じたから買うと言う理由になってしまう。
仕事を選ぶときには、給料は安いけど楽しいから みたいな、お金の部分はとりあえず切り離して考えるしか無くなる
美味しいものを食べたとき、高いものは美味しいなという貧相な感想になる
いい仕事をした人にいい給料を渡したとき、高いだけのことはあるねなんて失礼なことを言う羽目になる。

では、私は、また、そのような感性しか持ち合わせてない人はどのようにしてそのお金に対する感受性を養うのか。
何を皮切りに訓練を始めればいいのか。

いいものをたくさん見る と言うのが多分一番簡単で、一番安直だけどそれなりに効果がある方法なのではないか。
金銭的ではなく、人々の間に受け入れられているもの。多くの人が感情を動かされているものを多く見ることにより、
意識的でも打算的でもない無意識的なところから感じるものの共通項というか、それこそ何かを見つけることができるのかもしれない。
今僕は東京に住んでいる。東京は比較的お金が強い町だ。お金によって買えるものがたくさんあふれている。あらゆる物事がサービスとして提供されている。
ニューヨークとかもそうなのかもしれないけれど、東京みたいな大都市はあらゆる価値、あらゆる感性を金銭に変換する街なのかもしれない。

改めてもう一つ別の記事として書くと思うけど、僕は今、この金銭的価値の尺度を変えていきたいと思っている。
現状の消費行動としての金銭消費を、投票行動に昇華させる活動、仕事がしたいと思う。
その一番最初の活動として、アート作品の売買と徹底的に向き合ってみたいと思う。
そして最終的には、人の価値と金銭的関係に切り込んでいければと思う。

Posted By :
Comment :0