ITと創作でねこを飼いたい

プログラミングやITで勉強したこと、疑問をまとめます。

FlutterでFirebase Authenticationを利用したログイン済ユーザーの情報を取ってくる方法

完全に小ネタ
以下の記事を参考にしてFlutterでログイン機能を実装した。
FlutterでFirebase Authenticationを使ったGoogleアカウントログインを実装してみた

ただ、「ログインさせる方法」は分かったけど、「既にログインできているかどうかを確認する方法」はどうなんだろう? となった。

結論

import 'package:firebase_auth/firebase_auth.dart';

 final FirebaseAuth _auth = FirebaseAuth.instance;
 FirebaseUser user = await _auth.currentUser();

Android Stdio上でFirebaseAuthからメソッドあさって見つけた感じです。

余談

ちなみにFirestoreにユーザーを特定する情報として登録するなら、FirebaseAuthの中のuidがいいのかなーって思った。

uidの説明

The user's ID, unique to the Firebase project. Do NOT use this value to authenticate with your backend server, if you have one. Use User.getToken() instead.

参考サイト
Firebase でユーザーを管理する

Pythonチュートリアルを勉強して「こんな書き方・機能あったんだ」と思ったこと

はじめに

Python 3 エンジニア認定基礎試験の勉強に際して、Pythonのチュートリアルをやっていったのですが、「こんな書き方・機能あったんだ」みたいな、初心にかえったからこその発見があったので、ブログに残しておきたいと思います。

形式ばらない Python の紹介

↑【6問/40問中】出るところ

  • //の演算

小数部を切り捨てて、整数を返す。

  • **は累乗の計算

  • 対話モードでは、最後に表示された結果は変数「_」に代入されます。

  • 複素数j

電気系に優しい。

  • ¥に続く文字を特殊文字として解釈されたくない場合は、最初の引用符の前にrをつける

  • 連続して並んでいる複数の文字列リテラルは自動的に連結される

  • スライスで範囲外のインデックスを使った場合は、うまく対応して扱ってくれる(例えば以下のような感じ)

>>> word = 'Python'
 >>> word[4:42]
 'on'
 >>> word[42:]
 ''

その他の制御フローツール

↑【9問/40問中】出るところ

  • [ほぼ余談]input()関数

x=input()などしておけば、次に入力したものをxに代入することができます。 また、input(何か入力してください。: )なんてすれば、入力を促すメッセージも出力できます。

  • print(range(5))とすると、range(0, 5)と表示される。

  • 文を書くことが構文上要求されているが、プログラム上何の動作もする必要がないとき → pass文を使う。

  • 関数を別の名前に代入できる

  • returnの存在しない関数をprintするとNoneが表示される。

 >>> i=5
 >>>
 >>> def f(arg=i):
 ...     print(arg)
 ...
 >>> i=6
 >>> f()

5が表示される。

**随時更新予定

nginxのデフォルト画面を表示するCloudFormationのテンプレートファイル(yml)

今の現場でAWSを触っている& AWS 認定ソリューションアーキテクト–アソシエイトの資格も取得した!
けれどゼロからVPCとかサブネットとかEC2構築してって言われたら、まだ戸惑いそう……

てことで、自分のスキルの確立のために、
AWSの勉強の復習として、
CloudFormationのテンプレートファイルを作成することにしました。
(完全に備忘録です)

CloudFormationとは

AWS CloudFormation は Amazon Web Services リソースのモデル化およびセットアップに役立つサービスです。リソース管理に割く時間を減らし、AWS で実行するアプリケーションにさらに注力できるようになります。使用するすべての AWS リソース (Amazon EC2 インスタンスAmazon RDS DB インスタンスなど) を記述するテンプレートを作成すれば、AWS CloudFormation がお客様に代わってこれらのリソースのプロビジョニングや設定を受け持ちます。

つまりは、
テンプレートさえあれば、AWSのリソースのプロビジョニングや設定完成できるよーっていう話。

構成

VPC
Subnet : Private×3, Public×3(リージョンごとに一つずつ作成、備忘録として作成したので何もリソースを配置していない場所もある)
internet gateway
NAT gateway ALB
EC2
→Maintenance用にPublic Subnetに1台
→WEBサーバをPrivate Subnetに2台(リージョンは別)

テンプレート本体

私はコメント書けるので(現場でもこちらだったので)ymlで書いてます。

Github(今後も追加していきたいところ)

AWSTemplateFormatVersion: "2010-09-09"
Description: Memorandum of setting up AWS environment

# EC2のページでKeyは作成しておくこと
Parameters:
  WebKeyName:
    Description: The EC2 Key Pair to allow SSH access to the instance
    Type: AWS::EC2::KeyPair::KeyName

  ManagedKeyName:
    Description: The EC2 Key Pair to allow SSH access to the instance
    Type: AWS::EC2::KeyPair::KeyName

  SSHAccessSourceIP:
    Type: String
#
# NetworkAclはデフォルトにするものと仮定
#
Resources:
# ------------------------------------------------------------#
#  VPC
# ------------------------------------------------------------#
    MyVPC:
        Type: AWS::EC2::VPC
        Properties:
            CidrBlock: 10.0.0.0/16
            Tags:
            - Key: Name
              Value: MyVPC

    # InternetGateway Create
    InternetGateway:
        Type: AWS::EC2::InternetGateway
        Properties:
            Tags:
            - Key: Name
              Value: test-igw

    # IGW Attach
    InternetGatewayAttachment:
        Type: AWS::EC2::VPCGatewayAttachment
        Properties:
            InternetGatewayId: !Ref InternetGateway
            VpcId: !Ref MyVPC

# ------------------------------------------------------------#
#  Subnet
# ------------------------------------------------------------#
    # Public Subnet
    # Subnet Public1a
    PublicSubnet1a:
        Type: AWS::EC2::Subnet
        Properties:
            AvailabilityZone: ap-northeast-1a
            CidrBlock: 10.0.110.0/24
            VpcId: !Ref MyVPC
            Tags:
              - Key: Name
                Value: test-public-subnet-1a
    # Subnet Public1c
    PublicSubnet1c:
        Type: AWS::EC2::Subnet
        Properties:
            AvailabilityZone: ap-northeast-1c
            CidrBlock: 10.0.120.0/24
            VpcId: !Ref MyVPC
            Tags:
            - Key: Name
              Value: test-public-subnet-1c
    # Subnet Public1d
    PublicSubnet1d:
        Type: AWS::EC2::Subnet
        Properties:
            AvailabilityZone: ap-northeast-1d
            CidrBlock: 10.0.130.0/24
            VpcId: !Ref MyVPC
            Tags:
            - Key: Name
              Value: test-public-subnet-1d

    # Private Subnet
    # Subnet Private1a
    PrivateSubnet1a:
        Type: AWS::EC2::Subnet
        Properties:
            AvailabilityZone: ap-northeast-1a
            CidrBlock: 10.0.10.0/24
            VpcId: !Ref MyVPC
            Tags:
            - Key: Name
              Value: test-private-subnet-1a
    # Subnet Private1c
    PrivateSubnet1c:
        Type: AWS::EC2::Subnet
        Properties:
            AvailabilityZone: ap-northeast-1c
            CidrBlock: 10.0.20.0/24
            VpcId: !Ref MyVPC
            Tags:
            - Key: Name
              Value: test-private-subnet-1c
    # Subnet Private1d
    PrivateSubnet1d:
        Type: AWS::EC2::Subnet
        Properties:
            AvailabilityZone: ap-northeast-1d
            CidrBlock: 10.0.30.0/24
            VpcId: !Ref MyVPC
            Tags:
            - Key: Name
              Value: test-private-subnet-1d

# ------------------------------------------------------------#
# NAT Gateway AZ:A
# ------------------------------------------------------------#
    # ELPIP for NAT Gateway
    NATGatewayAEIP:
      Type: AWS::EC2::EIP
      Properties:
        Domain: vpc
    # NAT Gateway
    NATGatewayA:
      Type: AWS::EC2::NatGateway
      Properties:
        AllocationId: !GetAtt NATGatewayAEIP.AllocationId
        # memo : Only one setting
        SubnetId: !Ref PublicSubnet1a

# ------------------------------------------------------------#
#  RouteTable
# ------------------------------------------------------------#
    # Public RouteTable1a
    PublicRouteTable1a:
        Type: AWS::EC2::RouteTable
        Properties:
          VpcId: !Ref MyVPC
          Tags:
            - Key: Name
              Value: test-public-route-1a
    
    # Public RouteTable1c
    PublicRouteTable1c:
      Type: AWS::EC2::RouteTable
      Properties:
        VpcId: !Ref MyVPC
        Tags:
          - Key: Name
            Value: test-public-route-1c

    # Public RouteTable1c
    PublicRouteTable1d:
        Type: AWS::EC2::RouteTable
        Properties:
          VpcId: !Ref MyVPC
          Tags:
            - Key: Name
              Value: test-public-route-1d
            
    # Private RouteTable1a
    PrivateRouteTable1a:
      Type: AWS::EC2::RouteTable
      Properties:
        VpcId: !Ref MyVPC
        Tags:
          - Key: Name
            Value: test-private-route-1a
    
    # Private RouteTable1c
    PrivateRouteTable1c:
      Type: AWS::EC2::RouteTable
      Properties:
        VpcId: !Ref MyVPC
        Tags:
          - Key: Name
            Value: test-private-route-1c

    # Private RouteTable1d
    PrivateRouteTable1d:
        Type: AWS::EC2::RouteTable
        Properties:
          VpcId: !Ref MyVPC
          Tags:
            - Key: Name
              Value: test-private-route-1d

# ------------------------------------------------------------#
# Routing
# ------------------------------------------------------------#
    # Public
    # PublicRoute1a
    PublicRoute1a:
        Type: AWS::EC2::Route
        Properties:
          RouteTableId: !Ref PublicRouteTable1a
          DestinationCidrBlock: 0.0.0.0/0
          GatewayId: !Ref InternetGateway
    
    # PublicRoute1c
    PublicRoute1c:
      Type: AWS::EC2::Route
      Properties:
        RouteTableId: !Ref PublicRouteTable1c
        DestinationCidrBlock: 0.0.0.0/0
        GatewayId: !Ref InternetGateway

    # PublicRoute1d
    PublicRoute1d:
        Type: AWS::EC2::Route
        Properties:
          RouteTableId: !Ref PublicRouteTable1d
          DestinationCidrBlock: 0.0.0.0/0
          GatewayId: !Ref InternetGateway

    # Private
    # PrivateRoute1a
    PrivateRoute1a:
      Type: AWS::EC2::Route
      Properties:
        RouteTableId: !Ref PrivateRouteTable1a
        DestinationCidrBlock: 0.0.0.0/0
        NatGatewayId: !Ref NATGatewayA

    # PrivateRoute1c
    PrivateRoute1c:
      Type: AWS::EC2::Route
      Properties:
        RouteTableId: !Ref PrivateRouteTable1c
        DestinationCidrBlock: 0.0.0.0/0
        NatGatewayId: !Ref NATGatewayA

    # PrivateRoute1c
    PrivateRoute1d:
      Type: AWS::EC2::Route
      Properties:
        RouteTableId: !Ref PrivateRouteTable1d
        DestinationCidrBlock: 0.0.0.0/0
        NatGatewayId: !Ref NATGatewayA

# ------------------------------------------------------------#
# RouteTable Associate
# ------------------------------------------------------------#
    # PublicRouteTable Associate Subnet1a
    PublicSubnet1aRouteTableAssociation:
        Type: AWS::EC2::SubnetRouteTableAssociation
        Properties:
          SubnetId: !Ref PublicSubnet1a
          RouteTableId: !Ref PublicRouteTable1a
    
    # PublicRouteTable Associate Subnet1c
    PublicSubnet1cRouteTableAssociation:
      Type: AWS::EC2::SubnetRouteTableAssociation
      Properties:
        SubnetId: !Ref PublicSubnet1c
        RouteTableId: !Ref PublicRouteTable1c

    # PublicRouteTable Associate Subnet1d
    PublicSubnet1dRouteTableAssociation:
      Type: AWS::EC2::SubnetRouteTableAssociation
      Properties:
        SubnetId: !Ref PublicSubnet1d
        RouteTableId: !Ref PublicRouteTable1d

    # PrivateRouteTable Associate Subnet1a
    PrivateSubnet1aRouteTableAssociation:
      Type: AWS::EC2::SubnetRouteTableAssociation
      Properties:
        SubnetId: !Ref PrivateSubnet1a
        RouteTableId: !Ref PrivateRouteTable1a
    
    # PrivateRouteTable Associate Subnet1c
    PrivateSubnet1cRouteTableAssociation:
      Type: AWS::EC2::SubnetRouteTableAssociation
      Properties:
        SubnetId: !Ref PrivateSubnet1c
        RouteTableId: !Ref PrivateRouteTable1c

    # PrivateRouteTable Associate Subnet1d
    PrivateSubnet1dRouteTableAssociation:
        Type: AWS::EC2::SubnetRouteTableAssociation
        Properties:
          SubnetId: !Ref PrivateSubnet1d
          RouteTableId: !Ref PrivateRouteTable1d
# ------------------------------------------------------------#
# SecurityGroup
# ------------------------------------------------------------#

    # Managed
    ManagedSecurityGroup:
      Type: AWS::EC2::SecurityGroup
      Properties:
        GroupDescription: Managed EC2
        GroupName: Managed SecurityGroup
        VpcId: !Ref MyVPC
        Tags:
          - Key: Name
            Value: managed-sg
        # Rule
        SecurityGroupIngress:
          - IpProtocol: tcp
            FromPort: 22
            ToPort: 22
            CidrIp: !Ref SSHAccessSourceIP

    ManagedWebSecurityGroup:
      Type: AWS::EC2::SecurityGroup
      Properties:
        GroupDescription: Managed Web EC2
        GroupName: Managed Web SecurityGroup
        VpcId: !Ref MyVPC
        Tags:
          - Key: Name
            Value: managed-web-sg
        # Rule
        SecurityGroupIngress:
          - IpProtocol: tcp
            FromPort: 22
            ToPort: 22
            CidrIp: 10.0.110.0/24

    WebSecurityGroup:
      Type: AWS::EC2::SecurityGroup
      Properties:
        GroupDescription: web and ssh
        GroupName: web-sg
        VpcId: !Ref MyVPC
        Tags:
          - Key: Name
            Value: web-sg
    
    # Rule
    WebSecurityGroupIngress:
      Type: AWS::EC2::SecurityGroupIngress
      Properties:
        IpProtocol: tcp
        FromPort: 80
        ToPort: 80
        SourceSecurityGroupId: !GetAtt ALBSecurityGroup.GroupId
        GroupId: !GetAtt WebSecurityGroup.GroupId

    # ALB
    ALBSecurityGroup:
      Type: AWS::EC2::SecurityGroup
      Properties:
        GroupDescription: ALB
        GroupName: ALB SecurityGroup
        VpcId: !Ref MyVPC
        Tags:
          - Key: Name
            Value: alb-sg
        # Rule
        SecurityGroupIngress:
          - IpProtocol: tcp
            FromPort: 80
            ToPort: 80
            CidrIp: 0.0.0.0/0
          - IpProtocol: tcp
            FromPort: 443
            ToPort: 443
            CidrIp: 0.0.0.0/0
        SecurityGroupEgress:
          - IpProtocol: tcp
            FromPort: 80
            ToPort: 80
            DestinationSecurityGroupId: !Ref WebSecurityGroup

# ------------------------------------------------------------#
# EC2
# ------------------------------------------------------------#
    # Maintenance
    ManagedInstanceA:
      Type: AWS::EC2::Instance
      Properties:
        InstanceType: t2.micro
        ImageId: ami-0a1c2ec61571737db
        SecurityGroupIds:
          - !Ref ManagedSecurityGroup
        SubnetId: !Ref PublicSubnet1a
        KeyName: !Ref ManagedKeyName
        Tags:
          - Key: Name
            Value: Maintenance

    ManagedInstanceEIP:
      Type: AWS::EC2::EIP
      Properties:
        Domain: vpc
        InstanceId: !Ref ManagedInstanceA

    # Web
    WebInstanceA:
      Type: AWS::EC2::Instance
      Properties:
        InstanceType: t2.micro
        ImageId: ami-0a1c2ec61571737db
        SecurityGroupIds:
          - !Ref WebSecurityGroup
          - !Ref ManagedWebSecurityGroup
        SubnetId: !Ref PrivateSubnet1a
        KeyName: !Ref WebKeyName
        Tags:
          - Key: Name
            Value: Web-A
        UserData: !Base64 |
          #!/bin/bash
          sudo yum -y update
          sudo amazon-linux-extras install -y nginx1.12
          sudo service nginx start
    WebInstanceC:
      Type: AWS::EC2::Instance
      Properties:
        InstanceType: t2.micro
        ImageId: ami-0a1c2ec61571737db
        SecurityGroupIds:
          - !Ref WebSecurityGroup
          - !Ref ManagedWebSecurityGroup
        SubnetId: !Ref PrivateSubnet1c
        KeyName: !Ref WebKeyName
        Tags:
          - Key: Name
            Value: Web-C
        UserData: !Base64 |
          #!/bin/bash
          sudo yum -y update
          sudo amazon-linux-extras install -y nginx1.12
          sudo service nginx start
# ------------------------------------------------------------#
#  Target Group
# ------------------------------------------------------------#

    TargetGroup:
      Type: AWS::ElasticLoadBalancingV2::TargetGroup
      Properties:
        VpcId: !Ref MyVPC
        Name: web-tg
        Protocol: HTTP
        Port: 80
        HealthCheckProtocol: HTTP
        HealthCheckPath: /
        HealthCheckPort: traffic-port
        HealthyThresholdCount: 2
        UnhealthyThresholdCount: 2
        HealthCheckTimeoutSeconds: 5
        HealthCheckIntervalSeconds: 10
        Matcher:
          HttpCode: 200
        Tags:
          - Key: Name
            Value: web-tg
        TargetGroupAttributes:
          - Key: "deregistration_delay.timeout_seconds"
            Value: 300
          - Key: "stickiness.enabled"
            Value: false
          - Key: "stickiness.type"
            Value: lb_cookie
          - Key: "stickiness.lb_cookie.duration_seconds"
            Value: 86400
        Targets:
          - Id: !Ref WebInstanceA
          - Id: !Ref WebInstanceC
            Port: 80

# ------------------------------------------------------------#
#  Internet ALB
# ------------------------------------------------------------#

    InternetALB:
      Type: AWS::ElasticLoadBalancingV2::LoadBalancer
      Properties:
        Name: WebALB
        Tags:
          - Key: Name
            Value: WebALB
        Scheme: internet-facing
        LoadBalancerAttributes:
          - Key: deletion_protection.enabled
            Value: false
          - Key: idle_timeout.timeout_seconds
            Value: 60
        SecurityGroups:
          - !Ref ALBSecurityGroup
        Subnets:
          - !Ref PublicSubnet1a
          - !Ref PublicSubnet1c

    ALBListener:
      Type: AWS::ElasticLoadBalancingV2::Listener
      Properties:
        DefaultActions:
          - TargetGroupArn: !Ref TargetGroup
            Type: forward
        LoadBalancerArn: !Ref InternetALB
        Port: 80
        Protocol: HTTP

少し補足

今回のテンプレートはParametersはあまり設定しない方針です。
コメントに書いているように、EC2にアクセスするためのKeyは先に作成してください。
SSHAccessSourceIPは、Maintenanceサーバにアクセスすることができる唯一のIPとして設定します。
VPC, SubnetのIP(CIDR)の設定は適宜変更してください。

ちょっと他でみないのは、WEBサーバとしてたてたEC2のUserDataの部分でしょうか。

        UserData: !Base64 |
          #!/bin/bash
          sudo yum -y update
          sudo amazon-linux-extras install -y nginx1.12
          sudo service nginx start

AWSだとnginxはyumではなく、amazon-linux-extrasnginxでインストールしなければなりませんでした。
ここでnginxをstartさせておくことで、(EC2にSSH接続しなくても)ALBで指定されたDNSにアクセスしてnginxのデフォルト画面が表示されます。

おわりに

NAT gatewayが接続されていないPrivate Subnetだとyumが動かなかったり、
Private SubnetにWEBサーバおくにはALBが必要になったり……テンプレートファイル書くだけでかなりの復習になりました!!
今度は無料で動かせる範囲のLambdaの構築とかしたいです。

以上です!

きっと、あの日の僕は今の星野源を好きにはならなかった

2019年10月14日 「Same Thing」の配信リリースと共に、「おげんさんといっしょ」が放送されたこの日。
星野源ファンにとって、これほど至福な一日はなかったのではないだろうか。
海外ツアーを控えた彼にとっても、この日は特別な一日であったと思う。

おげんさんといっしょ。放送直後。10月15日0時00分00秒
強烈な音楽の余韻に浸る中で、しかし私はこう思っていた。

きっと、あの日の”僕”は今の星野源を好きにはならなかっただろう、と。

星野源の音楽との出会い

私の星野源との出会いは、ほんの少しだけ突拍子のないものだった。

それは、私が高校三年生の三月のことである。
私はその頃、受験も終わって、ただただ家で空虚な日々を過ごしていた。
第一志望の大学に落ちて滑り止めの私立に行くことになった私は、何かに負けてしまった、そんな喪失感を抱いていたのだ。
滑り止めの大学は入る学部も学科も適当に選んだところで、
私にあったのは希望でも目的でも目標でもなく、大きく鬱陶しい不安だけだった。

家でボーッとしながら、私は(わざわざ録画していた)「おじゃる丸スペシャル」を観ようと思った。
できれば「高校生にもなって」と笑わないで欲しい。
私は、あの独特な不思議な世界観が好きだったし、スペシャルだったら絶対面白いだろうとまで思っていたのだ。

その話は「銀河鉄道の夜」を題材にしたお話だった。

平日の真昼間から、幼児向けアニメを観ていた高校三年生は(実に滑稽なものだが)、エンディングになって唖然とした。
いや、あの日の衝撃は今でもうまく言葉にできない。驚いたし体中に電流が走ったし鳥肌が立った。そしてなぜだか少しだけ、涙が出ていた。

そのエンディングを歌っていたのが「星野源」だったのである。

文筆家で役者でアーティスト

ほんの少ししか流れなかった劇中の曲を、私は何度も何度も巻き戻して再生した。
何が私をそこまで掻き立てたのかは分からない。けれど、こんなにも惹き付けられる音楽との出会いは、私の人生にはかつてないものだった。

スマホを持ち始めたばかりで、まだまだインターネットに慣れていなかった私だったが、
衝撃のままに「誰だこの男の人は!?」と検索をする。

星野源」という名前とともに、自分が微かに涙した曲は「ある車掌」という名前であることを知った。
「ある車掌」がリリースされていなかったことに落胆しながら、私はYoutubeに挙がっていた星野源の曲を、「他にどんな歌を歌っているんだろう」と何の気なしに再生する。

びっくりした。全部好きだった。こんな都合のいいことがあるのかと思った。

その頃、Youtubeに挙がっていたのは「くせのうた」「日常」「くだらないの中に」「フィルム」だったと思う。「くせのうた」以外は通して聞くことはできなかった(この頃は源さんがこだわってわざとやっていることも知らなかった)

調べると、文筆家で役者で、「うんちを漏らしたことがある」というパワーワードまで出てきて、私は何だか星野源ワールドにすっかり魅了されてしまっていた。当時発売されていたアルバム「ばかのうた」「エピソード」を買って、しばらくすると我慢できなくなってシングルの「フィルム」も買っていた。

死にたくなるような曲を歌う人

今となっては、「そう言われていた」というソースを探すことの方が難しいが、(私の記憶を頼りに言うなら)、源さんはその頃「死にたくなるような(暗い)曲を歌う人」「”生活”を歌う人(キッチン・茶碗・老夫婦などがそう言われる所以であろう)」と呼称されていた。
確かにその頃は暗めの歌の方が多かった。歌い方にしても「スーダラ節」で観客を泣かせるほどである。しかし、ポップじゃないそれもよかったし、その頃の私にとってはそれがよかった。

そして源さんの曲は、私にとってただただ暗いだけでもなかったのである。

例えば、「ばらばら」と言う曲がある。
アルバム「ばかのうた」の1曲目であり、歌詞カードには「どん底の状態でポロっと出てきた曲」とまで書かれている曲だ。
暗いか明るいかで言えば、もちろん暗い。
けれど、源さんは歌詞の中で「世界は一つじゃなくていい、ばらばらのままでいいんだ」と、そう諭してくれる。
みんな結局ばらばらで、でも一つになる必要はない、ばらばらでいい。
分かっていたようで、分かっていなかった。そんな気付きがあって、その頃の私にはガツンとくるものがあった。

Mステ→いいとも→新曲発売

大学で一人暮らしを始めると、通学時間にイヤホンで源さんの歌を聴くのが日課になっていた。
友達とカラオケに行ったときも、空気なんて読まずに(みんな知らない曲が多かった)源さんの曲を歌いまくった。

そんな折、源さんが「夢の外へ」という楽曲でミュージックステーションに初登場することになる。
そのときの私の喜びようったらなかった。夢の外ではなく、夢の中のような心持ちで、高校時代の部活のLINEに「絶対いいから観て!」とメッセージまで送ったほどだ。

タモさんと相性良さそうだなぁーなんて思っていると、ほどなくして「いいとも」のテレフォンショッキングにゲストとして登場。お尻が急に痛くなる「モニカ病」という奇病の話は、声をたてて笑った。

そして、源さんは私をラジオの世界まで誘った。この頃、源さんがパーソナリティーを努めていたのは「RADIPEDIA」だった。全部聞けたわけではないし、正直細かい内容までは覚えていない。割りと下ネタをいうんだなぁーとか、ラジオのメンバーと仲がいいんだなぁーとかそんなかんじだった。

ただ、その頃の新曲「知らない」のラジオ初オンエアに立ち会ったことは、強烈に覚えている。(あまり好きになれなかったら、どうしようとか、そんな心配は皆目無用だった。)リアルタイムで、源さんに「イヤホンで音量を上げて!」と言われるままに聴いた「知らない」は、私をまた源さんの虜にした。

くも膜下出血

私が大学1年生だった頃の源さんは、世の中に広く露出し始めた怒涛の1年間を過ごしていたように思う。

その1年間の最後にニュースに上がったのが、源さんのくも膜下出血の報だった。

動揺して、たかだか一ファンでしかないが、心配だった。
病名が病名だけに、病気前と同じ健康体には戻れないのかもしれないと唇を噛んだ。
一度復帰したかと思って、もう一度活動休止になったときは、「全快してくれ、無理しないでくれ」と、信じて願うことしかできなかった。

そんな真っ只中に発売されたのが、シングル「地獄でなぜ悪い」である。

奈落の底から化けた僕をせり上げてく ~化物より~

このシングルの特典DVDを、(他の特典DVDと違って)私はつらくて数回しか観れていない。それは、顔は出ないまでも、病床の源さんの様子が垣間見えたからだ。DVDではもちろん明るい風だったが、それでも源さん、そしてスタッフの不安や葛藤が伝わってきて、胸をつくようなつらさがあった。

ライブからの紅白

2回目の活動休止を越え復活した折、私は初めての源さんのライブ(星野源の復活アアアアア‼)に行くことができた。
実は、アーティストのライブにまともに行ったのは、これが初めてだった。

すごかった。自分の文章力が足りなくてうまく表現ですることができないができないけれど、”心が震える”とはこういうことなんだと思った。ただの歌なのに、こんなにも人の心に響き、人の人生をも変えてしまいそうな力があった。

また、このライブではあの人気キャラクター(?)ニセ明さんも初登場する。
ニセ明さんが生まれたきっかけは、源さんが入院中にやることがなく、カラオケのオモチャで「君は薔薇より美しい」を練習していたことにより生まれたキャラクターということだった。(おそらくこのライブの口上でしかなかった話だと思う)
今は、ニセ明さんが出る度に笑みが溢れてしまうものだが、元々は暗い入院生活で生まれたものだったと思うと感慨深いものがある。

そして2015年12月31日、源さんは紅白に初出場を果たす。
イカ大王様やバナナマンに紹介されながら、歌唱した「SUN」
「祈り、届くなら」と歌いながら涙を浮かべていた姿は、一ファンとして熱くくるものがあった。

そして怒濤の快進撃

2016年:ドラマ「逃げるは恥だが役に立つ」出演/楽曲「恋」の発表/恋ダンス 社会現象に等しかった。
2017年:楽曲「Family Song」 曲に込められた家族観の話を聞いたときは、胸にくるものがあった。
2018年:朝ドラ主題歌「アイデア」の発表 2番を配信ダウンロードで聴いたときは、何故だかじんわりと涙が出てきた。年末に発売されたPOP VIRUSも最高でしかなかった。

そして昨年2019年、星野源がアーティストとして配信したのがEP「Same Thing」だった。

突然の配信発表。全編英語の歌詞。 海外ツアーが始まることは知っていたが、「まさか」と言ってしまいそうなラインナップだった。
同じ星野源が歌っていることには変わりはない。昔も今も根底は変わらない。源さんから言わせれば「同じこと」だ。
けれど、ファンからすると今までの星野源とは一線を画す「新しさ」があるように思った。

これからの僕と星野源

あの日。
鬱々と家で、無為な時を過ごしていた少年の"僕"が、例えば「Same Thing」を聴いて、ここまで星野源の曲を、彼の世界を好きになれていただろうか?

多分、答えは否だ。

それは一面から見れば、寂しいことなのかもしれない。
きっとあの日の"僕"は、源さんのことを「人気らしいアーティストが、紅白でまた歌ってる」くらいにしかとらえられなかった。

でも、それでいいのだと思う。
源さんは、進化し変わっていった。
そして"僕"も変わったのだ。

今、変わらず源さんのことが好きな、源さんの見せてくれる新しい音楽、新しい世界が好きな"僕"でいられて、私は自分を誇りに思っている。

あとがき

2019年10月14日のおげんさんといっしょを観た興奮から、
"僕"と星野源について書いてみたが、いつの間にやら年まで越してしまった。
(紅白のおげんさんバージョン「ドラえもん」からの良音質「Same Thing」は堪らなかった)

ここまで書いておいてなんだが、自分のことを星野源の"ヘビーな"ファンとまで言っていいかはちょっと分からない。
毎週オールナイト日本を聴いているという訳でもないし、源さんがインスタ始めたからとインスタに飛びついた(折をみて始めたいのだが……)という訳でもないのだ。(引越し大名は観にいったと弁明しておく)
SAKEROCKから応援していたわけでもないので、古参としても中途半端なんだと思う。

でもファンの形も「ばらばら」でいいんだと、私は信じている。
きっと私とは違った思いで、この10年近い日々を過ごしたファンも大勢いることだろう。
そもそも私が書いたことは、源さんの望む音楽体験だったとも限らないのだ。

(自分でもびっくりする)長文になってしまったが、、、あくまで一ファンの戯言だと思っていただけたら幸いだ。
これからも源さんの見せる世界に、"僕"のペースでついて行きたいと思う。

2020年1月2日

【勉強会レポート】 Android Dev Summit2019報告会(主催: GDG Osaka)

自社のSlack投稿用に勉強会レポートを書いていたので、(折角なんで)ブログにも転用しようと思います!

行った勉強会

【大阪】Android Dev Summit2019報告会(主催: GDG Osaka) gdgosaka.connpass.com

内容は、Android Dev Summit2019を元にしたものでした!

ちなみにGDGとはGoogleのテクノロジーに興味、関心があるメンバーが集うグループ

一番印象深かったこと

話題に挙がっていて、直近でも役立ちそうな情報は「Android Stdio 4.0」の話でした!
該当セッション : What’s New in Android Stdio

http:// https://youtu.be/XPMrnR1_Biw

セッション中身についての箇条書き

  • gradle3.5以上(バグがあるらしいの3.5.2 以上がベスト)にするとBuildスピードが格段に上がる。
  • Buildスピードを可視化する機能が追加
  • build.gradleに以下を追加してBuildすると
 compileOptions{
     coreLibraryDesugaringEnabled = true
 }

古いAPIレベルでより高いAPIレベルを必要とするAPIにアクセスできる。
(割とびっくりな話ではないかと・・)

とのこと。
Android Stdio 利用される方は4.0試してみるといいかもしれません!

その他

  • Android Dev Summit2019のsessionの中で一番多かったのは「Jetpack」の内容だったらしい。
  • もうすぐアプリ購入等に「Cash purchases」が始まる(今のところ日本、インド、メキシコのみ)
    (ちなみにplay pointsって日本と韓国だけしかないらしいですね、知らなかったです)
  • 結構びっくりなプレゼント企画とかもあったので、かなり勢いのある団体かと思います!!

新規作成したファイルを選別してgit stashしたい

私が試した小技の話。
git stashの説明については以下を参照してください。
git stashすごく便利)

qiita.com

やりたいこと

タイトルの意味が伝わっているのか否か、微妙なところだと思う。
まずそもそもの話、git stashは新規作成した(untrackedな)ファイルはstashしない」
という特徴がある。(今まで追跡してなかったものは退避しないという考え方)

issueの区切りとか、開発の切れ目でstashしたい!!というときはちょっと不便。
で、やりたかったことは、追跡してなかったファイルの中でも.gitignoreファイルは残して、他のファイル(追跡したものも含めて)をstashしたかった。

新規作成したファイルも含めてstashする

これはオプションuをつければ解決できる。
ただこれだけでは、新規作成したファイルから、どれをstashしてどれをstashしないのか選ぶことはできない。

stashしたい変更を選択する

これは一般的にはgit addでも使うであろう、オプションpをつければ良い。
しかし、オプションupは同時に指定することができない。

オプションkを組み合わせる!!

オプションkというものがある。
公式の説明をgoogle翻訳に突っ込むと、

インデックスにすでに追加されているすべての変更はそのまま残ります。

とのこと。
ということで stashしたくない新規ファイルをaddしておいてオプションuとkを使ってstashする ことで、擬似的に私のやりたかったことを実現します。

コマンドで書くとこんな感じ↓

# gitignoreファイル(stashしたくない新規ファイル)をインデックスに追加しておく
git add gitignore

# オプションkとuを駆使
git stash save -k -u "メッセージの追加も可能"

注意事項

オプションkは、インデックスに残した変更を 残す だけで、 インデックスした変更をstashしないわけでなはない 模様(インデックスも実はstashされている)

stashを適用するときにstashしたときにaddしていたファイルをインデックスから戻しておくと、無駄にコンフリクトがおきたりする。

つまりは、上記の方法でstashした場合は、stashしたときの状態に戻してから適用する必要があるのでご注意を(もちろん、インデックスしていたファイルに何かしらの変更を加えていた場合は普通にコンフリクトするかと思う)

個人的には違和感のある仕様ではあるが、、
gitignoreファイルを避けるくらいだったら、上に挙げた方法で特段問題はなかった。

DynamoDBからエクスポートしたCSVファイルをインポートしたい

既存で用意されているDynamoDBのテーブルと、同じ定義のテーブルを作る機会があった。で、開発時に使っていたテストデータを新しいテーブルに移したいなぁ、と思ったのが事の発端。

既存のtableのデータのエクスポート

エクスポートは簡単。
1、AWSコンソールのサービスDynamoDBを開く。
2、左メニューから「テーブル」を選択し、項目タブを開く。
3、エクスポートしたいデータを選択する。
4、AWSコンソールの「アクション」から「CSVへエクスポート」を選択。

テーブル名でCSVファイルがダウンロードされる。

インポートの正攻法

コンソール画面を見てもらったら分かると思うが、
残念なことにアクションの中に「CSVファイルのインポート」はない。

あっても良くない? と思わなくもないが「CSVファイルのインポート」の機能はNoSQLの思想に反するのかも、、しれない。

で、データを一気に入れたいときどうするんだよって話だが、
正攻法は以下っぽい。

dev.classmethod.jp

データを整形してS3にupするとか、なんかめんどうそう・・・

面倒そうなので非正攻法の手段を作ってみた

AWS CLIaws dynamodb put-item ~コマンドを使えば、DynamoDBにデータを入れることができる。
コマンドってのはこんな感じのやつ

aws dynamodb put-item --table-name 「テーブル名」 --item '{ "項目名": { "定義 (NとかSとか)": "値" }, "項目名": { "定義 (NとかSとか)": "値" }, ~~  "項目名": { "定義 (NとかSとか)": "値" } }'

上記コマンドの仕組みを利用して
DynamoDBのコンソール画面からエクスポートしたCSVファイルからAWS CLIのコマンドをshellファイルとして作成するプログラム
を作ってみました。

github.com

前提条件
AWS CLIの設定が完了している。
Python 3系が入っていてPandasが利用できる(動作確認は3.7.2でやっている)

使い方
1、ソースをクローンしてきて、同じフォルダ内にエクスポートしてきたCSVファイルを入れる。
(数行のソースなので、コピーして使ってもらっても大丈夫だと思う)
2、コマンドを叩く。

python create_insert_command.py [元のテーブル名] [新しいテーブル名]

元のテーブル名とは、正確にいうとエクスポートしたcsvファイルの[ここの部分].csv(test.csvならtest)

シェルファイルは、「新しいテーブル名」_import_「日付情報」.shの名称で同じフォルダ内に作成される。

第二引数は省略可能。省略した場合は、エクスポートを実施したテーブルと同じ名前でコマンドが生成される。つまり、シェルを実行すると、エクスポート先と同じテーブルにデータが書き込まれる。
(引数がない場合はリポジトリ内のimporttest.csvをコマンドに変換する)
3、シェルファイルを実行すれば、エクスポートしたデータがDynamoDBにimportされるという寸法

注意点
・Pandasを使用したので、データが多い場合はコマンド生成に時間がかかる可能性がある。
・大量の書き込みだと、結構お金がかかるかも?
・値にダブルクォーテーションなんかがあると、コマンドでエラーがでる可能性が高い。(今のところはテキストエディタでうまく置換してもらうしか回避方法なし)

あまり、大量のデータの場合は向かないかもしれませんが、
ちょっとしたデータだったら使えるんじゃないかと思いますー。