Cloud Firestoreに登録されたデータをtimestamp順に取得する

序章

Firebaseのサービス「Cloud Firestore」にデータを記録し、そこから取得したデータを表示するWebサイトを作りました。単純に取得して表示したところ、登録順にデータは表示されず、謎の順番で表示されてしまうのでした。

firebase.google.com

原因

FirebaseのCloud Firestoreでは、addDoc()メソッドを使用してデータを追加すると、ユニークなランダムなIDが自動的に割り当てられているようで、そのユニークなID順で表示されている模様。

 

解決方法

Firestoreのドキュメントに特定のフィールドを追加し、そのフィールドを使用してデータをソートする事で解決します。

 

具体的な解決コード

  const [posts, setPosts] = useState([]);

  useEffect(() => {
    const postData = collection(db, "posts");
    const queryRef = query(postData, orderBy("timestamp"));

    getDocs(queryRef).then((querySnapshot) => {
      const data = querySnapshot.docs.map((doc) => ({ ...doc.data() }));
      setPosts(data);
    });


query()を使い、第2引数でtimestampを指定してソートします。

    const queryRef = query(postData, orderBy("timestamp"));

 

gueryRefからドキュメント一覧を取得し、querySnapshotに格納します。

    getDocs(queryRef).then((querySnapshot) => {

 

querySnapshotから一つ一つドキュメントデータを取得し、dataに格納します。

      const data = querySnapshot.docs.map((doc) => ({ ...doc.data() }));

 

上記の流れで無事タイムスタンプ順にデータを取得できました。

 

追記

import {
  collection,
  getDocs,
  addDoc,
  Timestamp,
  onSnapshot,
  doc,
  query,
  orderBy,
} from "firebase/firestore";

 

importを忘れずに!

create-react-appで作成した環境に環境変数を設定

序章

Firebaseを使い、データベースに接続するReactアプリを作成にチャレンジした際、

firebase.js内の

const firebaseConfig = {

で設定する情報を環境変数から取得する記述方法に変更したかった。

 

作成するファイル

.envファイルをプロジェクトのルート直下に作成します。

.envの中に

REACT_APP_API_KEY=xxxxxx
REACT_APP_AUTH_DOMAIN=xxxxxx
REACT_APP_DATABASE_URL=xxxxxx

のような記述で設定したい環境変数を記載します。

 

ポイントは、「REACT_APP_」から開始する事。

REACT_APP_から開始されていない環境変数無視されてしまうようです。

create-react-app.dev

変更後のfirebase.js

// Your web app's Firebase configuration
const firebaseConfig = {
apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.REACT_APP_FIREBASE_APP_ID,
};

 

process.env.****

という記述で、.envファイルに定義した環境変数と無事紐付けることに成功しました。

 

Bashプロンプト上にgitブランチ名を表示する

実現したい事

gitで管理しているフォルダに滞在している時、どのブランチにいるのか。分かりやすくしたい。具体的なゴールは以下のような見た目にする事です。

gitブランチフォルダを表示

手段

bashシェルの環境変数PS1を書き換える事で実現します。

(PS1変数は、プロンプトの形式を設定する環境変数

 

PS1変数の設定

~/.bashrcに以下のコードを追加します。

PROMPT_COMMAND='update_PS1'
update_PS1() {
    if [ -d ".git" ]; then
        BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
        PS1='\[\e[36m\]\u@\h:\[\e[m\]\[\e[32m\]\w\[\e[m\] \[\e[31m\](${BRANCH})\[\e[m\]\n$ '
    else
        PS1='\[\e[36m\]\u@\h:\[\e[m\]\[\e[32m\]\w\[\e[m\]\n$ '
    fi
}

 

処理の流れは以下になります。

  1. PROMPT_COMMANDに関数(update_PS1)を登録。
  2. update_PS1では、gitで管理しているフォルダか?判定し、PS1変数を設定。

<PROMPT_COMMAND:bashシェルがコマンドを実行する前に行うコマンドを設定>

 

上記を.bashrcに追記する事で、gitで管理しているフォルダに入るとブランチ名も表示されるようになります。

 

動作確認

.bashrcを保存した後、

$ source ~/.bashrc

 

を入力し、変更を有効にしてください。その後、新しいターミナルを開くと実現出来ているはずです。

 

WSL2上でsystemctlコマンドを実行できない事を解決

序章

いつインストールしたのか?忘れたほど昔に入れたWSL2を動かしました。

OSとして動かしてのはUbuntu。windows11 -> WSL2 -> Ubuntuという構成。です。

 

この環境下でphpを学習する環境構築を開始しようと色々模索していたのですが、

その過程で

「sudo systemctl status apache2」を実行すると

 

System has not been booted with systemd as init system (PID 1). Can't operate. Failed to connect to bus: Host is down

 

というエラーメッセージが出てしまいました。それを解決するまで調べた事を記事に

纏めておきます。

 

エラーが出てしまう原因

systemctlを実行するには、Linux上で最初に起動するプロセス PID 1 (Process ID 1)がsystemdである事が必要であるが、PID1がsystemdではない為。エラーになっています。

 

プロセスの確認方法

ps -aux

コマンドを入力する事で、プロセスの状態を把握します。

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 2324 1504 ? Sl 15:02 0:00 /init

 

PID 1をみると、systemdではなく、init になっている事が分かります。

 

解決方法(概要)

PID1を initではなく、systemdに変更しましょう。

 

WSL2のバージョン確認

コマンドプロンプト上で wsl --version と入力し、WSL2のバージョンが表示されるか?確認してください。

 

WSL バージョン: 1.1.6.0
カーネル バージョン: 5.15.90.1
WSLg バージョン: 1.0.50
MSRDC バージョン: 1.2.3770
Direct3D バージョン: 1.608.2-61064218
DXCore バージョン: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows バージョン: 10.0.22621.1413

 

上記のようにバージョンがずらずらと表示されれば、インストールされているWSL2は

Microsoft Store版」です。

しかし、上記のような表示がされず、wslのコマンドヘルプが出るのであれば、入っているWSL2は「Windows コンポーネント版」です。

 

Windows コンポーネント版に対する対応策もあるようですが、本記事ではそちらには触れません。素直に、Windows コンポーネント版をMicrosoft Store版に変更して下さい。

 

変更するにはコマンドプロンプトにて「wsl --update」と入力します。

updateが開始され、自動的にMicrosoft Store版に変更されるはずです。

 

解決方法(本題)

Ubuntu上に/etc/wsl.confを作成し、wsl.confに以下を記述します。

[boot]
systemd=true

 

ファイル保存した後、コマンドプロンプトで「wsl --shutdown」を入力し、wslを再起動させます。その後、Ubuntuを立ち上げるとsystemctlを使う事が出来るようになっています。

 

ps -auxで変化を見てみてください。

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 165888 11064 ? Ss 16:22 0:00 /sbin/init

今度はPID1が /sbin/initに変更されています。

 

/sbin/initはシンボリックリンクになっており、実際には

lrwxrwxrwx 1 root root 20 Sep 10 2022 init -> /lib/systemd/systemd*

systemdが使われている事になります。

 

参考記事

【WSL2】systemctlが動かない問題をきちんと解決する | しきゆらの備忘録

 

devblogs.microsoft.com

 

atmarkit.itmedia.co.jp

 

ascii.jp