- 投稿日:2020-09-25T21:08:17+09:00
Android でFIS_AUTH_ERRORエラー Firebaseプッシュ通知が届かない
はじめに
運営しているアプリを機種変更してから初めて起動すると突如、このようなエラーに見舞われた。。。。
環境
Ionic 5 + Angular で開発したのネイティブアプリ
Ionic プッシュ通知を送るテスト(Capacitor)
この記事と全く同じやり方でプッシュ通知を実装しました。解決までにやったこと
※結論から言うと、解決はしてません。。。
Google Cloud PlatformでAPIの制限を追加
ずっと、「キーを制限しない」になっていたが、追加してみた。
The FIS_AUTH_ERROR means Authentication for Firebase installation sdk has failed.
https://stackoverflow.com/questions/60698622/java-io-ioexception-fis-auth-error-in-android-firebase
と言うことらしいので。
Firebase SDK を追加する
こちらを参考に、
app/build.gradle
に以下を追加dependencies { // 省略 implementation 'com.google.firebase:firebase-messaging:20.1.2' implementation 'com.google.firebase:firebase-analytics:17.5.0' }しかしながら、Using Push Notifications with Firebase in an Ionic + Angular Appのドキュメントでは、以下のような記述がある。
We don't need to add any dependencies to our project because Capacitor projects automatically include a version of firebase-messaging in it's build.gradle file.
何もdependenciesに追加する必要はない、と言っているが、、、とりあえず追加してみよう。
google-services.jsonを新しく入れ替える
Firebaseコンソール画面からプロジェクトを選択>設定>マイアプリ
の項目から新しくgoogle-services.jsonをダウンロード。そして置き換える。
エラーは消えたが、プッシュ通知を目視することはできなかった!!!
2020-09-25 19:35:13.665 15955-15955/com.hCalendar.app I/Capacitor/Console: File: http://localhost/common.js - Line 371 - Msg: プッシュ通知を受け取ったよ: {"id":"0:1601030113498713%b2260e4cb2260e4c","data":{},"title":"寒くなりましたね。。","body":"人肌を重ねてあったまりましょう"} 2020-09-25 19:35:13.811 15955-16488/com.hCalendar.app D/FA: Connected to remote service 2020-09-25 19:35:48.363 15955-15955/com.hCalendar.app I/Ads: Use RequestConfiguration.Builder().setTestDeviceIds(Arrays.asList("01C5204CC8216A22615E0A6DF7BDDD97") to get test ads on this device. 2020-09-25 19:35:48.393 15955-16288/com.hCalendar.app W/m.hCalendar.ap: Accessing hidden method Lsun/misc/Unsafe;->getObject(Ljava/lang/Object;J)Ljava/lang/Object; (greylist, linking, allowed) 2020-09-25 19:35:48.393 15955-16288/com.hCalendar.app W/m.結局エラーは消えたが、プッシュ通知は確認できなかった。。。(コンソール上のログでは確認できてるので、一応届いてはいる???)
うーん。。。どうすればいいんだろう??
どなたか情報提供お願いします参考
https://stackoverflow.com/questions/60698622/java-io-ioexception-fis-auth-error-in-android-firebase
- 投稿日:2020-09-25T18:53:07+09:00
12. 【Android/Kotlin】丸いイメージ(CircleImageView)
はじめに
DreamHanksのMOONです。
前回はToastという通知メッセージについて説明ししました。
11. 【Android/Kotlin】Toast今回は
CircleImageView
という外部ライブラリを使用していきます。ライブラリを追加する方法については下記のリンクで確認してください。
10. 【Android/Kotlin】ライブラリを追加CircleImageViewとは
皆さんはラインや他のアプリで丸い写真のイメージを見たことがあると思います。
それがCircleImageViewで変換されたイメージです。
CircleImageViewは原本のイメージを丸いイメージに変換してくれるImageViewのライブラリです。
CircleImageView追加
・CircleImageViewのライブラリを追加
buile.gradleにのdependenciesに下記のコードを追加implementation 'de.hdodenhof:circleimageview:3.1.0'・Activityを作成
CircleImageViewActivity.ktpackage com.example.practiceapplication import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.* class CircleImageViewActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_circleimageview) } }activity_circleimageview.xml<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".CircleImageViewActivity" android:gravity="center"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="原本のイメージ"/> <ImageView android:layout_width="300dp" android:layout_height="300dp" android:id="@+id/org_iv" android:src="@drawable/dreamhanks"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="丸いイメージ"/> <de.hdodenhof.circleimageview.CircleImageView android:layout_width="300dp" android:layout_height="300dp" android:src="@drawable/dreamhanks" android:id="@+id/circle_iv"/> </LinearLayout>CircleImageViewのViewタグを追加します。
アプリ起動
終わりに
今回は
CircleImageView
という外部ライブラリを使用してみました。
- 投稿日:2020-09-25T17:18:06+09:00
Chrome Custom Tabs で強制的に Chrome で表示する方法
概要
例えば AndroidManifest.xml の
<intent-filter>
にAndroidManifest.xml<intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:host="example.com" android:scheme="https" /> </intent-filter>と定義していた場合、Chrome Custom Tabs で
https://example.com/
のページを表示しようとすると
intent-filter の条件に一致するため、こんな感じで Chrome 以外の候補が表示されてしまいます。
この候補モーダルを表示させずに強制的に Chrome で表示する方法です。
方法
MainActivity.ktval builder: CustomTabsIntent.Builder = CustomTabsIntent.Builder() val customTabsIntent: CustomTabsIntent = builder.build() if (packageManager.getLaunchIntentForPackage("com.android.chrome") != null) { customTabsIntent.intent.setPackage("com.android.chrome") } customTabsIntent.launchUrl(this, Uri.parse(url))
setPackage()
で Chrome のパッケージ名を指定してあげるだけです。念のため
getLaunchIntentForPackage()
で Chrome が存在しているかチェックしています。
↑ では存在しなかったときの処理はなにも行っていませんが本来であればエラーメッセージを表示するなどしてあげたほうが良いかと思います。以上です。
参考
- 投稿日:2020-09-25T15:34:25+09:00
生成された図で見るDagger Hiltへのマイグレーション
Dagger Hiltへのマイグレーションのコードラボは数ヶ月前にやっていて忘れてきたので、どういう内容だったのか後から振り替えれるようにグラフをおいておきます。
ちょっと先にDagger Hiltのチュートリアル的なのは他の記事などでご確認ください。https://codelabs.developers.google.com/codelabs/android-dagger-to-hilt/#1
またDagger SPIを使ったいい感じのGradle Pluginも見つけたのでそれで見ていきます。
https://github.com/arunkumar9t2/scabbard今Daggerをグラフ化して見るのはDaggerの公式SPI(Service provider interface)を使っているこれが良さそうかも? https://t.co/IzVaZJofuo
— takahirom (@new_runnable) September 25, 2020マイグレーション前
Daggerでは、DaggerのComponent、DIコンテナでオブジェクトをインスタンス化するためのロジック(コンストラクションロジック)とインスタンスが保持されています。
AppComponentにはアプリケーション全体で保持するコンストラクションロジックとインスタンスを保持しており、RegistrationComponentには登録のときに使うコンストラクションロジックとインスタンスが入っています。コンポーネントの木
今回はSubComponentという仕組みが使われており、コンポーネント同士が依存することができ木構造になっており、RegistrationComponentではAppComponentの内容が使えるようになっています。コードでのSubComponentの作り方(詳細は説明しません)
@Singleton @Component(modules = [StorageModule::class, AppSubcomponents::class]) interface AppComponent { ... // サブコンポーネントのFactoryを取得できるようにする fun registrationComponent(): RegistrationComponent.Factory fun loginComponent(): LoginComponent.Factory ... } @Module( subcomponents = [ // サブコンポーネントを指定する RegistrationComponent::class, LoginComponent::class, UserComponent::class ] ) class AppSubcomponents @ActivityScope @Subcomponent interface RegistrationComponent { @Subcomponent.Factory interface Factory { fun create(): RegistrationComponent } ... }そしてRegistrationComponentとLoginComponentでは
@ActivityScope
と書いており、これを使うことでこのComponentのDIコンテナを指定してインスタンスを配布したり、同じインスタンスを共有したりできるようにしているようです。 (このサンプルでは、ViewModelがこの@ActivityScope
になっている)@ActivityScope @Subcomponent interface LoginComponent { ... }@ActivityScope class RegistrationViewModel @Inject constructor(val userManager: UserManager) {
中間までマイグレーション
Dagger HiltではDaggerのアプリのコンポーネントの構造を標準化するので、このようにActivityComponent(内部的にはActivityRetainedC)などのComponentが追加されています。
中間までのマイグレーションなので、UserComponentが残っています。Dagger Hiltのコード生成によって、ActivityComponent(内部的にはActivityRetainedC)など勝手にSubCompopnentが作られます。
しかし、UserComponentは自分で作ったComopnentなので、生成させられません。
どのようにしたかというと、InstallIn
でApplicationComponentにModuleを追加し、そこでsubcomponentsを指定しています。@InstallIn(ApplicationComponent::class) @Module( subcomponents = [ UserComponent::class ] ) class AppSubcomponentsそしてUserComponent.FactoryをUserManagerにInjectさせることで、UserComponentを作成し利用できます。
@Singleton class UserManager @Inject constructor( private val storage: Storage, private val userComponentFactory: UserComponent.Factory ) {ただ、UserComponentはDagger Hiltの外のComponentなので、このUserComponentの管理は自分で行う必要があります。
@Singleton class UserManager @Inject constructor( private val storage: Storage, private val userComponentFactory: UserComponent.Factory ) { var userComponent: UserComponent? = null private set ... fun registerUser(username: String, password: String) { ... userJustLoggedIn() } fun loginUser(username: String, password: String): Boolean { ... userJustLoggedIn() return true } fun logout() { // When the user logs out, we remove the instance of UserComponent from memory userComponent = null } private fun userJustLoggedIn() { userComponent = userComponentFactory.create() } }ここでUserComponentによるInjectを使う上で一つ問題があります。
MainActivityでUserComponentによるInjectが使うためには、UserManagerのインスタンスが必要です。UserComponentのDIコンテナでInjectしたいのでMainActivityには@AndroidEntryPoint
をつけてHiltのInjectを使うことができません。
こういうときにDagger HiltのDIコンテナが持つインスタンスを受け取る方法があります。EntryPointAccessor
を使うというもので、これによってUserManagerを取得して、UserManagerのもつuserComponentでinjectが可能になります。class MainActivity : AppCompatActivity() { @InstallIn(ApplicationComponent::class) @EntryPoint interface UserManagerEntryPoint { fun userManager(): UserManager } ... override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Grabs instance of UserManager from the application graph val entryPoint = EntryPointAccessors.fromApplication(applicationContext, UserManagerEntryPoint::class.java) val userManager = entryPoint.userManager() ... userManager.userComponent!!.inject(this) ... }
マイグレーション後
完全にUserComponentが削除されており、HiltのComponentが完全に使われています。
ちなみに
@Singleton
なUserRepositoryを使って、その中でログイン中かなどを管理することで、解決しているようです。
- 投稿日:2020-09-25T15:11:48+09:00
エンジニア就職に向けてマッチングアプリ(Androidアプリ)を作ってみた
はじめに
こんにちは。タイトルにもある通りエンジニア就職のためにマッチングアプリ『Match-com(マッチコン)』を作成しました。
開発期間はおおよそ1ヶ月半です。
1年ちょっと前まではSESに9ヶ月ほど在籍していました。それ以降は少しエンジニアから離れて別のことをやっていましたが最近になってまたこの業界に戻ってきました。(プログラミングの学習自体は続けてました)どんなアプリ?
男性と女性のマッチングアプリです。皆さんも一度は使ったことがあるんじゃないでしょうか。
お互いがいいねをしたらマッチングしてチャットができるようになります。主な機能
・Firebase
・メールログイン/Facebookログイン
・プロフィール登録
・いいね!
・マッチング
・リアルタイムチャット
・ブロック
・写真登録/プロフィール編集
・新規メッセージとマッチング時のPush通知
・退会独自の機能を盛り込んで今あるサービスと差別化を図る予定でしたが細かいところまで拘っていたら思った以上に開発に時間がかかってしまいました。
とりあえず最低限の機能は実装して形にはなったので一旦これで就職活動を始めて落ち着いたらまた色々と機能を追加していく予定です。※現在、丸2日経っても審査中のためまだリリースができていません。リリース次第こちらにURLを貼り付けます。
苦労したこと
・バグ
バグには苦労させられました。一度、完成したと思っても開発を進めていくうちにおかしな挙動を発見したりアプリ自体が落ちてしまうこともありました。達成感に満ち溢れてるところから落とされるのはかなりきついです。何度もアタックしてやっと付き合えた彼女に3日で振られるような、そんな感覚です。
・設計の甘さ
今まで自分がやったことのない機能の開発は初めてのことばかりでかなり時間がかかりました。
これまでも簡単なアプリなら作ったことはあったのですが大体今までの知識の流用で事足りていました。しかし、今回は割と本格的に作ったので色々と調べて自分のコードで動作するように改変しながら実装していきました。特に最初にちゃんとした設計をやっていなかったところもあり、何度も書いたコードを修正したりと設計の重要性を再認識できた一方で変なところで時間が取られてしまったりともう少し効率よく開発できれば良かったと思います。
・わからない言葉が多い
調べごとをしているとわからない言葉がたくさん出てきます。必要そうなことは都度調べて開発していたのですがアプリの完成を第一目標にした場合、さすがに全ての言葉を一回一回調べていると時間がなくなるのでとりあえず後回しにした言葉も結構ありました。実際に開発現場でそういう言葉がバンバン飛び交うのを想像すると少し気が重くなりました。開発してみて良かったこと
・ドキュメントを読む癖
今回の開発ではFirebaseを本格導入したのですがそこでドキュメントを読み解く癖がついたのがいい経験になりました。
もちろん、Qiitaの記事や日本語の参考資料など有益なものもたくさんありましたが細かい話になるとドキュメントや英語の記事を読み漁る必要があったので結果的にドキュメントに対するアレルギーというものが大幅に軽減できました。・英語の重要性
よく「エンジニアになるのに英語は必要か」みたいな議論がありますがエンジニアに就職するためなら必ずしも必要というわけではないですがこれから自分でプログラミングを学んでいく上で絶対できた方が効率いいよね、と思う場面は何度もありました。
日本語で探してやっとたどり着いた記事の内容が英語で検索すると一番上にある、なんていうのはザラにあったからです。今回のアプリを日本語の資料だけで実装しろと言われたらかなり時間がかかると思います。・情報を整理する力
簡単な実装ならチュートリアル的なものを見つけてちょこっと修正すればそれで済むと思います。
しかし、複雑なことをしようと思うと当然1つの情報源で全てが解決するということは稀でインターネット上のいくつかの情報を組み合わせて自分のケースに落とし込むというのが必要になってきます。
しっかりとしたアプリケーションを作ろうと思うと、こうした「情報を総合して解釈する能力」というのが自然と身に付いてくると感じました。・やり切った自信
アプリを作る前と後だとだいぶ開発に対しての自信がつきました。
最初は本当に完成させられるのか不安が90%くらいでしたが実際に完成させてみると、ある程度のアプリなら作れそうと思えるようになりました。
やはり教材でずっと勉強しているよりも何かを作った方が応用力がつくので結果的に実力向上に結びつきやすいです。結局は作りながら学ぶのが一番です。
ただ最初の知識が少なすぎるとパワーで無理やり実装してしまうところも出てくるのである程度体系だった知識を学んでから、実際に作ってみて今ある知識に肉付けしていくというやり方でもいいと思います。アプリ紹介
以上で作ったアプリの簡単な概要はおしまいです。これ以降は作ったアプリの紹介になるので時間がある方は見てみてください。(少し長くなります!)
基本的に上で列挙した機能を順に紹介していくスタイルにしようと思います。直感的にわかるように文字は少なめで画像や動画を多めに使っています。gifではうまくupできなかったのでこちらを参考にしてTwitterに上げたものを使っています。Firebase
今回はバックエンドにFirebaseを使用しました。NoSQLはRDBのようにテーブルの結合ができなかったため最初は戸惑いましたが慣れてくると非常に使い勝手が良くスムーズに使えるようになりました。
使用したサービス
・Authentication
・Realtime Database
・Cloud Firestore
・Cloud Storage(画像の保存に利用)
・Cloud Messaging(Push通知に利用)
・Dynamic Links(メールリンクに使用)メールログイン / Facebookログイン
画面はこんな感じです。
メールアドレスでログインする場合はメールを入力してサインインボタンを押すとパスコードが発行されるので送られてきたメールのリンクからアドレスと発行コードを入力して登録orログインします。
このメールリンクの機能はDynamic Linksを使用しています。
https://firebase.google.com/docs/dynamic-links/android/receive?hl=jaFacebookログインの場合は友達が10人以上いないと登録できません。
ユーザーの友達の数を取得するのにはFacebookのGraph APIというものを使用しました。
https://developers.facebook.com/docs/graph-api/overviewプロフィール登録
上記の方法でログインが完了するとそのユーザーが新規のユーザーかを判定します。
すでに存在するユーザーであればホームスクリーン、新規のユーザーであればプロフィール登録画面に進みます。ここのプロフィールは全て入力しないとボタンが非活性になります。
(※QiitaでうまくgifをupできなかったためTwitterを使ってます。)— komei_401 (@401Komei) September 24, 2020いいね!
右スワイプでいいね、左スワイプでごめんね、となります。
— komei_401 (@401Komei) September 24, 2020
写真をタップすると次の写真に移動できます。名前以下のところをタップするとユーザーの詳細画面に飛ぶことができます。
— komei_401 (@401Komei) September 24, 2020マッチング
相手も自分にいいねをしていた場合、そこでマッチング成立となります。
— komei_401 (@401Komei) September 24, 2020リアルタイムチャット
こちらがチャット一覧画面です。これとチャット画面に一番時間がかかりました。
「マッチングしたお相手」というのがマッチはしたが会話はしてない人、「会話中のお相手」が実際に会話中の人になります。マッチして24時間以内なら上にNew!とつきます。(黒で塗りつぶしてあるのはフリー素材以外の写真を使用していたからです。)
「会話中のお相手」の写真の左上にある◯はそのユーザーのログインステータスになります。
緑 → オンライン
黄色 → 最終ログインから24時間以内
灰色 → 最終ログインから24時間以上メッセージを送ると「会話中のお相手」に移動します。
— komei_401 (@401Komei) September 24, 2020チャット画面はこんな感じです。
意外にメッセージの上にある日付を入れるのに苦労しました笑
別にここは簡単な実装で良かったんですがなるべくreal-world project的なものを作りたかったので地味に拘ってしまいました。今日のメッセージは今日、昨日のものは昨日、それ以外は日付、今年以外のものは年も含めて表示するようにしています。メッセージはもちろん写真も送信することができます。
— komei_401 (@401Komei) September 24, 2020またチャット画面のアイコンからを相手ユーザーの詳細画面に飛べます。
— komei_401 (@401Komei) September 24, 2020ブロック
ユーザーをブロックすると会話中の相手からいなくなります。
— komei_401 (@401Komei) September 24, 2020写真登録/プロフィール編集
写真はクロッピングして登録します。
— komei_401 (@401Komei) September 24, 2020メイン写真と入れ替えることもできます。
— komei_401 (@401Komei) September 24, 2020削除した写真が2枚目だった場合、3枚目の写真は左につめます。間を写真のない状態にしないということですね。
— komei_401 (@401Komei) September 24, 2020趣味と言語を登録する時は入力したものがチップとなって溜まっていきます。最後に更新ボタンを押して更新完了です。
— komei_401 (@401Komei) September 24, 2020新規メッセージとマッチング時のPush通知
新着のメッセージを受信するとPush通知が送られてきます。
— komei_401 (@401Komei) September 24, 2020
また文字だけでなく画像もPush通知で送ることができます。
— komei_401 (@401Komei) September 24, 2020
Push通知を本格的に実装しようとすると結構大変でした。普通にやるとアプリを開いている時は受信できるが閉じると受信できなくなってしまうからです。アプリを閉じたときでも受信できるようにするには1 : FirebaseのCloud Functionsを使用してRealtime Database更新のタイミングでPush通知を送るよう実装する
2 : FirebaseMessagingServiceを継承したクラスを作り、onMessageReceivedメソッドをオーバーライドして通知した際の処理を実装し、デバイス間の通信を実現このどちらかの方法で実装する必要がありました。自分は2の方法で実装しました。デバイス間の通信にはRetrofitを利用しています。
1の方法でもNode.jsなどでローカルで実装してCLIからFirebaseにdeployすればイケると思います。
退会
最後に退会機能です。これはプロフィール編集画面の一番下から行うことができます。
— komei_401 (@401Komei) September 24, 2020まとめ
本格的にアプリを開発したのは初めてだったので作り終わったあとの達成感もありましたが同時に疲労感もありました。これからアプリを開発する人はなるべく設計を意識した方がいいと思います。
じゃないと何度もコードを修正したり、依存性の強いコードを書いたりしてしまいます。
Solid原則を常に意識しておくと良いでしょう。こちらの記事が参考になります。こういうのを読んでみるのもいいかもしれません。(自分はまだ読んだことないですが)
https://www.amazon.co.jp/dp/B07FSBHS2V/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1アウトプットは今回で十分やったのでしばらくはまたインプットの量を増やして学習を継続していこうと思います。
最後まで読んでいただき、ありがとうございました。
- 投稿日:2020-09-25T15:11:48+09:00
マッチングアプリ(Androidアプリ)を作りました
はじめに
こんにちは。エンジニア就職のためにマッチングアプリ『Match-com(マッチコン)』を作成しました。
開発期間はおおよそ1ヶ月半です。どんなアプリ?
男性と女性のマッチングアプリです。皆さんも一度は使ったことがあるんじゃないでしょうか。
お互いがいいねをしたらマッチングしてチャットができるようになります。主な機能
・Firebase
・メールログイン/Facebookログイン
・プロフィール登録
・いいね!
・マッチング
・リアルタイムチャット
・ブロック
・写真登録/プロフィール編集
・新規メッセージとマッチング時のPush通知
・退会独自の機能を盛り込む予定でしたが細かいところまで拘っていたら思った以上に開発に時間がかかってしまいました。
とりあえず最低限の機能は実装して形にはなったので一旦これで就職活動を始めて落ち着いたらまた色々と機能を追加していく予定です。※現在、丸2日経っても審査中のためまだリリースができていません。リリース次第こちらにURLを貼り付けます。
苦労したこと
・バグ
バグには苦労させられました。一度、完成したと思っても開発を進めていくうちにおかしな挙動を発見したりアプリ自体が落ちてしまうこともありました。達成感に満ち溢れてるところから落とされるのはかなりきついです。何度もアタックしてやっと付き合えた彼女に3日で振られるような、そんな感覚です。
・設計の甘さ
今まで自分がやったことのない機能の開発は初めてのことばかりでかなり時間がかかりました。
これまでも簡単なアプリなら作ったことはあったのですが大体今までの知識の流用で事足りていました。しかし、今回は割と本格的に作ったので色々と調べて自分のコードで動作するように改変しながら実装していきました。特に最初にちゃんとした設計をやっていなかったところもあり、何度も書いたコードを修正したりと設計の重要性を再認識できた一方で変なところで時間が取られてしまったりともう少し効率よく開発できれば良かったと思います。
・わからない言葉が多い
調べごとをしているとわからない言葉がたくさん出てきます。必要そうなことは都度調べて開発していたのですがアプリの完成を第一目標にした場合、さすがに全ての言葉を一回一回調べていると時間がなくなるのでとりあえず後回しにした言葉も結構ありました。開発してみて良かったこと
・ドキュメントを読む癖
今回の開発ではFirebaseを本格導入したのですがそこでドキュメントを読み解く癖がついたのがいい経験になりました。
もちろん、Qiitaの記事や日本語の参考資料など有益なものもたくさんありましたが細かい話になるとドキュメントや英語の記事を読み漁る必要があったので結果的にドキュメントに対するアレルギーというものが大幅に軽減できました。・英語の重要性
よく「エンジニアになるのに英語は必要か」みたいな議論がありますがエンジニアに就職するためなら必ずしも必要というわけではないですがこれから自分でプログラミングを学んでいく上で絶対できた方が効率いいよね、と思う場面は何度もありました。
日本語で探してやっとたどり着いた記事の内容が英語で検索すると一番上にある、なんていうのはザラにあったからです。今回のアプリを日本語の資料だけで実装しろと言われたらかなり時間がかかると思います。・情報を整理する力
簡単な実装ならチュートリアル的なものを見つけてちょこっと修正すればそれで済むと思います。
しかし、複雑なことをしようと思うと当然1つの情報源で全てが解決するということは稀でインターネット上のいくつかの情報を組み合わせて自分のケースに落とし込むというのが必要になってきます。
しっかりとしたアプリケーションを作ろうと思うと、こうした「情報を総合して解釈する能力」というのが自然と身に付いてくると感じました。・やり切った自信
アプリを作る前と後だとだいぶ開発に対しての自信がつきました。
最初は本当に完成させられるのか不安が90%くらいでしたが実際に完成させてみると、ある程度のアプリなら作れそうと思えるようになりました。
やはり教材でずっと勉強しているよりも何かを作った方が応用力がつくので結果的に実力向上に結びつきやすいです。結局は作りながら学ぶのが一番です。
ただ最初の知識が少なすぎるとパワーで無理やり実装してしまうところも出てくるのである程度体系だった知識を学んでから、実際に作ってみて今ある知識に肉付けしていくというやり方でもいいと思います。アプリ紹介
以上で作ったアプリの簡単な概要はおしまいです。これ以降は作ったアプリの紹介になるので時間がある方は見てみてください。(少し長くなります!)
基本的に上で列挙した機能を順に紹介していくスタイルにしようと思います。直感的にわかるように文字は少なめで画像や動画を多めに使っています。gifではうまくupできなかったのでこちらを参考にしてTwitterに上げたものを使っています。Firebase
今回はバックエンドにFirebaseを使用しました。NoSQLはRDBのようにテーブルの結合ができなかったため最初は戸惑いましたが慣れてくると非常に使い勝手が良くスムーズに使えるようになりました。
使用したサービス
・Authentication
・Realtime Database
・Cloud Firestore
・Cloud Storage(画像の保存に利用)
・Cloud Messaging(Push通知に利用)
・Dynamic Links(メールリンクに使用)メールログイン / Facebookログイン
画面はこんな感じです。
メールアドレスでログインする場合はメールを入力してサインインボタンを押すとパスコードが発行されるので送られてきたメールのリンクからアドレスと発行コードを入力して登録orログインします。
このメールリンクの機能はDynamic Linksを使用しています。
https://firebase.google.com/docs/dynamic-links/android/receive?hl=jaFacebookログインの場合は友達が10人以上いないと登録できません。
ユーザーの友達の数を取得するのにはFacebookのGraph APIというものを使用しました。
https://developers.facebook.com/docs/graph-api/overviewプロフィール登録
上記の方法でログインが完了するとそのユーザーが新規のユーザーかを判定します。
すでに存在するユーザーであればホームスクリーン、新規のユーザーであればプロフィール登録画面に進みます。ここのプロフィールは全て入力しないとボタンが非活性になります。
(※QiitaでうまくgifをupできなかったためTwitterを使ってます。)— komei_401 (@401Komei) September 24, 2020いいね!
右スワイプでいいね、左スワイプでごめんね、となります。
— komei_401 (@401Komei) September 24, 2020
写真をタップすると次の写真に移動できます。名前以下のところをタップするとユーザーの詳細画面に飛ぶことができます。
— komei_401 (@401Komei) September 24, 2020マッチング
相手も自分にいいねをしていた場合、そこでマッチング成立となります。
— komei_401 (@401Komei) September 24, 2020リアルタイムチャット
こちらがチャット一覧画面です。これとチャット画面に一番時間がかかりました。
「マッチングしたお相手」というのがマッチはしたが会話はしてない人、「会話中のお相手」が実際に会話中の人になります。マッチして24時間以内なら上にNew!とつきます。(黒で塗りつぶしてあるのはフリー素材以外の写真を使用していたからです。)
「会話中のお相手」の写真の左上にある◯はそのユーザーのログインステータスになります。
緑 → オンライン
黄色 → 最終ログインから24時間以内
灰色 → 最終ログインから24時間以上メッセージを送ると「会話中のお相手」に移動します。
— komei_401 (@401Komei) September 24, 2020チャット画面はこんな感じです。
意外にメッセージの上にある日付を入れるのに苦労しました笑
別にここは簡単な実装で良かったんですがなるべくreal-world project的なものを作りたかったので地味に拘ってしまいました。今日のメッセージは今日、昨日のものは昨日、それ以外は日付、今年以外のものは年も含めて表示するようにしています。メッセージはもちろん写真も送信することができます。
— komei_401 (@401Komei) September 24, 2020またチャット画面のアイコンからを相手ユーザーの詳細画面に飛べます。
— komei_401 (@401Komei) September 24, 2020ブロック
ユーザーをブロックすると会話中の相手からいなくなります。
— komei_401 (@401Komei) September 24, 2020写真登録/プロフィール編集
写真はクロッピングして登録します。
— komei_401 (@401Komei) September 24, 2020メイン写真と入れ替えることもできます。
— komei_401 (@401Komei) September 24, 2020削除した写真が2枚目だった場合、3枚目の写真は左につめます。間を写真のない状態にしないということですね。
— komei_401 (@401Komei) September 24, 2020趣味と言語を登録する時は入力したものがチップとなって溜まっていきます。最後に更新ボタンを押して更新完了です。
— komei_401 (@401Komei) September 24, 2020新規メッセージとマッチング時のPush通知
新着のメッセージを受信するとPush通知が送られてきます。
— komei_401 (@401Komei) September 24, 2020
また文字だけでなく画像もPush通知で送ることができます。
— komei_401 (@401Komei) September 24, 2020
Push通知を本格的に実装しようとすると結構大変でした。普通にやるとアプリを開いている時は受信できるが閉じると受信できなくなってしまうからです。アプリを閉じたときでも受信できるようにするには1 : FirebaseのCloud Functionsを使用してRealtime Database更新のタイミングでPush通知を送るよう実装する
2 : FirebaseMessagingServiceを継承したクラスを作り、onMessageReceivedメソッドをオーバーライドして通知した際の処理を実装し、デバイス間の通信を実現このどちらかの方法で実装する必要がありました。自分は2の方法で実装しました。デバイス間の通信にはRetrofitを利用しています。
1の方法でもNode.jsなどでローカルで実装してCLIからFirebaseにdeployすればイケると思います。
退会
最後に退会機能です。これはプロフィール編集画面の一番下から行うことができます。
— komei_401 (@401Komei) September 24, 2020まとめ
本格的にアプリを開発したのは初めてだったので作り終わったあとの達成感もありましたが同時に疲労感もありました。これからアプリを開発する人はなるべく設計を意識した方がいいと思います。
じゃないと何度もコードを修正したり、依存性の強いコードを書いたりしてしまいます。
Solid原則を常に意識しておくと良いでしょう。こちらの記事が参考になります。こういうのを読んでみるのもいいかもしれません。(自分はまだ読んだことないですが)
https://www.amazon.co.jp/dp/B07FSBHS2V/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1アウトプットは今回で十分やったのでしばらくはまたインプットの量を増やして学習を継続していこうと思います。
最後まで読んでいただき、ありがとうございました。
- 投稿日:2020-09-25T12:22:03+09:00
Android SDK platform-tools 旧バージョン インストール
結論
Xの部分を欲しいリビジョン番号に書き換えます。
https://dl.google.com/android/repository/platform-tools_rXX.X.X-darwin.zip
URLの雛形が変わった場合の対応方法
URLの雛形が変わる場合があるので、雛形入手の手順も記載しておきます。
URLの雛形
Android SDK platform-toolsに関する情報は下記を参照します。
https://developer.android.com/studio/releases/platform-tools.html
最新版は画面トップでインストールできるので、まずは最新版インストールのURLを入手しましょう。
入手したURL
https://dl.google.com/android/repository/platform-tools-latest-darwin.zip
欲しいリビジョン番号の入手
画面を下にスクロールすると過去のリビジョンについての情報が記載されてます。
欲しい番号を入手しましょう。
※画面上部にある言語設定はEnglishにしましょう。他の言語だと更新されてない場合があります。https://developer.android.com/studio/releases/platform-tools.html
URLの雛形の
tools-latest
の部分を欲しいリビジョン番号で書き換えます。
https://dl.google.com/android/repository/platform-tools_r29.0.6-darwin.zip
これでダウンロードできます。
参考
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q14182946004
- 投稿日:2020-09-25T01:30:48+09:00
Ubuntu18.04にAndroid Studio4系を入れる
Android Studioは公式サイトから落としてきて展開しても良いが、面倒。
snap install android-studio --classicと
snap
を使うとすんなり入り、android-studio
コマンドで起動できる。別途、Androidのエミュレータ起動のために関連ライブラリを入れた上で、kvmへのパーミッションが通るようにしたらok。
sudo apt install qemu-kvm -y sudo adduser $USER kvm sudo chown $USER /dev/kvm自分の環境では、PC再起動で反映された。