Docs Menu
Docs Home
/ /
Atlas App Services

チュートリアル: Atlas Device Sync for React Native

項目一覧

  • 前提条件
  • テンプレート アプリを使用する
  • テンプレート アプリの設定
  • 依存関係のインストール
  • アプリをビルドする
  • アプリをテストする
  • テンプレートアプリに慣れる
  • Atlas App Services App
  • React Native アプリ
  • 優先度レベルフィールドを追加する
  • 優先順位を定義する
  • Itemデータモデルを更新する
  • 優先度ピッカーを追加する
  • アプリを実行・テストする
  • 同期サブスクリプションを更新する
  • UI にモード トグルを追加する
  • 同期サブスクリプションを更新する
  • アプリをテストする
  • 次のステップ

完了までの推定時間: 30分(React Native の経験により異なります)

RealmReact Native SDKと @realm/React を使用できます でモバイルReact Native アプリケーションを構築できます。このチュートリアルでは、Flexible Sync を使用する独自のアプリを構築する方法について説明しています。

このチュートリアルでは、事前に構築された TypeScript テンプレート アプリケーションから始めて、すべてがどのように組み合わされるかについて説明しています。

このアプリは、動作する React Native アプリケーション(フロントエンド)とそれに対応する App Services App 構成ファイル(バックエンド)を含む事前構築済みのテンプレートです。

テンプレート アプリは、ユーザーがタスクを管理するためにさまざまなことを行うことができる To Do リストの基本アプリケーションです。

  • 電子メール/パスワード アカウントを作成し、アプリにログインまたはログアウトします。

  • 自分のタスクを作成、読み取り、更新、削除します。

  • ユーザーが所有者でない場合でも、すべてのタスクを表示します。

テンプレート アプリを実行したら、既存のItemモデルに新しい priority フィールドを追加し、Flexible Sync サブスクリプションを更新して、優先度の範囲内のアイテムのみを表示します。この例では、テンプレート アプリを独自のニーズに合わせて調整する方法について説明しています。テンプレート アプリの現在の構造を考慮すると、必ずしもこの変更を行う必要はありません。

テンプレートアプリには、デバイスがオフラインモードになっていることをシミュレートするトグルが用意されています。このトグルを使用すると、Device Sync 機能を素早くテストして、インターネットに接続していないユーザーをエミュレートできます。ただし、本番アプリケーションでは、ユーザーがこのトグル削除する可能性が高いでしょう。

注意

クイック スタートを確認する

ガイド付きチュートリアルに従うのではなく、自分で調べたい場合は、 React Native クイック スタートを確認できます。コピー可能なコード サンプルと、Atlas Device Sync を使用して React Native アプリを設定するために必要な重要な情報が含まれています。

  • このチュートリアルを開始する前に、React Native 開発用のローカル環境を設定する必要があります。手順について詳しくは、React Native ドキュメントの「 開発環境の設定」セクションを参照してください。

  • このチュートリアルは、テンプレート アプリから始めます。 テンプレート アプリを作成するには、 Atlas アカウント、 API キー、 App Services CLI が必要です。

    • Atlas アカウントの作成の詳細については、「 Atlas の使用開始」ドキュメントを参照してください。 このチュートリアルでは、無料階層クラスターを持つ Atlas アカウントが必要です。

    • ログインする MongoDB Cloud アカウントの Atlas API キーも必要です。 App Services CLI を使用してテンプレート アプリを作成するには、プロジェクト オーナーである必要があります。

    • App Services CLI のインストールについて詳しくは、「 App Services CLI のインストール」を参照してください。 インストール後、Atlas プロジェクトの API キーを使用して「 login 」コマンドを実行します。

このチュートリアルは、 react-native.todo.flexという名前の React Native SDK Flexible Sync テンプレート アプリを基本にして作成されており、デフォルトのアプリから始めて、新しい機能について説明しています。

テンプレート アプリの詳細については、「テンプレート アプリ 」を参照してください。

Atlas アカウントがまだない場合は、テンプレート アプリを配置するためにサインアップしてください。

App Services App」ガイドに記載されている手順に従い、 Create App from Templateを選択します。Real-time Sync テンプレートを選択します。これにより、Device Sync テンプレート App Services App クライアントの 1 つで使用するために事前構成された App Services App が作成されます。

テンプレート アプリを作成すると、UI に Get the Front-end Code for your Template というラベルの付いたモーダルが表示されます。このモーダルには、テンプレート アプリのクライアントコードを .zip ファイルとしてダウンロードする方法や、App Services CLI を使用してクライアントを取得する方法が表示されます。

.zip または App Services CLI メソッドを選択した後、画面の指示に従ってクライアント コードを取得します。このチュートリアルでは、JavaScript (React Native) クライアント コードを選択します。

注意

デフォルトの Windows ZIP ユーティリティで、.zip ファイルが空白ファイルとして表示される。この問題が発生した場合は、利用可能なサードパーティの zip プログラムのいずれかを使用してください。

appservices apps create コマンドでバックエンドを設定し、React Native テンプレート アプリを作成してこのチュートリアルのベースとして使用します。

ターミナル ウィンドウで次のコマンドを実行して、「Myチュートリアル App」という名前のアプリを作成し、環境が「開発」(本番環境やQAではなく)に設定されているUS-VAリージョンに配置されます。

appservices app create \
--name MyTutorialApp \
--template react-native.todo.flex \
--deployment-model global \
--environment development

このコマンドは、 --nameフラグの値と同じ名前で現在のパスに新しいディレクトリを作成します。

Device Sync クライアントコードを含む Github リポジトリをフォークしてクローンできます。React Native クライアント コードは https://github.com/mongodb/template-app-react-native-todo で入手できます。

このプロセスを使用してクライアントのコードを取得する場合は、クライアントで使用するテンプレート アプリを作成する必要があります。 「テンプレート アプリの作成」 の手順に従って、Atlas App Services UI、App Services CLI、または管理 API を使用して Device Sync テンプレート アプリを作成します。

テンプレート アプリをコンピューター上で起動して実行するには、次の手順に従います。

1

ターミナルで、クライアント・コードのあるディレクトリに移動します。App Services CLI を使用してアプリを作成した場合は、 MyTutorialApp/react-native.todo.flexに進みます。そうでない場合は、ダウンロードまたはクローンしたプロジェクトのルートに移動します。次に、次のコマンドを実行して、アプリの依存関係のインストールに移動します。

npm install

iOS デバイスまたはシミュレーターでアプリをビルドして実行するには、 CocoaPods を使用して追加の iOS 依存関係をインストールします。

cd ios
npx pod-install
2

この時点で、iOS、Android、またはその両方で実行できる、完全に機能する React Native アプリが完成しているはずです。

エラーが発生した場合やその他の問題が発生した場合は、React Native 環境が正しく設定されていることを確認してください。公式の「React Native 開発環境のセットアップ」ガイドを参照してください。開発 OS とターゲット OS のすべての手順に従います。

すべての機能が iOS で動作することを確認するには、アプリをビルドして iOS シミュレーターで実行します。

npm run ios

以下の方法で、すべての機能が Android で動作するか確認できます。

  1. Android エミュレータを起動します。詳しい方法については、「Android Emulator でのアプリの実行」を参照してください。

  2. エミュレータでアプリをビルドします。

    npm run android

    Error: spawn ./gradlew EACCES はよくあるエラーの 1 つで、プロジェクト ファイルのアクセス権限が適切ではないことを意味します。MacOS でこのエラーを修正するには、ターミナルに chmod 755 android/gradlew と入力します。

3

ビルドが完了すると、シミュレーター上で機能するアプリが実行されるはずです。アプリで、新しいアカウントを登録して、機能をテストします。

  • いくつかの To Do アイテムをリストに追加します。

  • 1 つまたは 2 つのアイテムのチェックボックスをオンにして、「完了」としてマークします。

  • アイテムの上でXを押すと、そのアイテムがリストから削除されます。

  • アプリ内でインターネット接続を切り替えて、オフライン モードをシミュレートします。

Atlas クラスターに接続してtodo.Itemコレクションをクエリすると、アプリのデータを表示できます。React Native アプリがオフライン モードでない限り、アプリ内の新しいデータと変更は自動的にtodo.Item コレクションに同期されます。

Tip

Atlas Cluster に接続する方法については、「クラスターへの接続」を参照してください。

同様に、コレクション内のすべての変更は React Native アプリに自動的に同期されます。クラスター内のアイテムの完了ステータスを変更してみてください。React Nativeアプリは、ネットワーク接続が利用可能になるたびに、新しい値で自動的に更新されます。

Tip

クラスター内のデータの更新について詳しくは、「ドキュメントの更新」を参照してください。

テンプレート アプリが実行できたので、コードを調べて、何を扱っているか確認してみましょう。

テンプレート アプリには、 backendディレクトリに完全に構成された App Services Appが含まれています。クライアント アプリケーションが接続に使用するatlasConfig.json内のユニークな appId 値があります。

また、次の事前定義された構成も含まれています。

  • Atlas Cluster にリンクされたデータソース。

  • React Native アプリの Item クラスに一致する todo.Item コレクションのデータ モデル。

  • ユーザーがメールとパスワードを使用してアプリに登録し、ログインできるようにする認証プロバイダ。

  • 1 つのセッションロールによる柔軟な同期構成により、ユーザーは自分のアイテムの読み取りと書込みを行ったり、他のユーザーのアイテムを表示したりできます。

React Native アプリは、iOS および Android デバイスで実行できる完全に構成されたモバイル クライアントです。

このアプリでは、@realm/react ライブラリが使用されます。このライブラリには、Atlas バックエンドと Realm データベースの操作を効率化する React フックとコンポーネントが含まれています。

アプリにはいくつかの構成ファイルとディレクトリが含まれていますが、アプリをカスタマイズする場合を除き、それらは無視できます。このチュートリアルでは、 source/ ディレクトリ内の React コンポーネントについて理解している必要があります。

ファイル名
説明
ItemSchema.tsx
Item クラス(オブジェクト データモデルを含む)。このクラスを AppWrapper.tsx にインポートして、アプリ全体の Realm スキーマに含めます。
AppWrapper.tsx
これは、アプリのルート コンポーネントです。これはラッパー コンポーネントとして機能し、すべての @realm/react プロバイダーが含まれます。ここで、Realm と Atlas バックエンドへの接続を構成します。
App.tsx
アプリの機能のほとんどは、このコンポーネントとその子に含まれています。@realm/react プロバイダーがこのコンポーネントをラップしているため、Atlas バックエンドのインスタンス、ユーザー オブジェクトにアクセスし、Realm データベースと対話することができます。
WelcomeView.tsx
ユーザーが最初にアプリを開いたときに表示されるユーザー登録とログイン フォーム。
ItemListView.tsx
ユーザーがログイン後に操作するメインの ToDo リスト アプリ。Item Realm オブジェクトを照会し、リストに表示します。また、新しい Item オブジェクトを作成して Realm に保存するコードも含まれています。
CreateToDoPrompt.tsx
新しい Item オブジェクトのデータを入力できる UI フォーム。実際に新しいオブジェクトを生成するコードは ItemListView.tsx にあります。
LogoutButton.tsx
認証されたユーザーをログアウトする再利用可能なボタン。
OfflineModeButton.tsx
現在の Realm syncSession を一時停止および再開することでオフライン モードをシミュレートする再利用可能なボタン。

テンプレート アプリにすでに用意されている機能について理解できたので、新しい機能を実装するコードを記述してみましょう。

このチュートリアルでは、 Item オブジェクトに新しい priority プロパティを追加します。これにより、ToDo を重要度別に整理し、最も重要なものにのみ集中できるようになります。

1

少数の名前付き優先レベルを許可し、レベルを簡単に並べ替えられるようにしたいと考えています。そのために、ヘルパー関数を使用して enum オブジェクトを定義します。このオブジェクトは、順序付けられたレベル名のセットを、優先順位を表す整数にマッピングしたり、レベル名から割り当てたりします。

source/ItemSchema.tsx のインポート ステートメントの直下に次のコードを追加します。

function createEnum(arr) {
arr.forEach((p, i) => arr[p] = i);
return arr;
}
// Priority.High === 1
// Priority[Priority.High] === "High"
export const Priority = createEnum([
"Severe",
"High",
"Medium",
"Low",
])

enum 内の優先度レベルは、最も重要なものから最も重要でないものの順に並べられています。各レベルに対応するインデックス値は、最も重要な Priority[0] から最も重要でない Priority[3] まで増加します。つまり、優先度が高いほど(つまり、より重要であるほど)、インデックス値は低くなります。

2

これで、 priority フィールドの可能な値を定義する enum ができました。ただし、 Item クラスで priority フィールドを定義する必要があります。

priorityItem データ モデルに追加するには、source/ItemSchema.tsx のコードに次の行を追加します。

source/ItemSchema.tsx
export class Item extends Realm.Object<Item> {
_id!: BSON.ObjectId;
isComplete!: boolean;
summary!: string;
owner_id!: string;
priority!: string;
static schema: Realm.ObjectSchema = {
name: 'Item',
primaryKey: '_id',
properties: {
// This allows us to automatically generate a unique _id for each Item
_id: {type: 'objectId', default: () => new BSON.ObjectId()},
// All todo items will default to incomplete
isComplete: {type: 'bool', default: false},
summary: 'string',
owner_id: 'string',
priority: {
// Store the index value of the Priority enum rather than the name
type: 'int',
default: Priority.High
},
},
};
}

注意

同期が壊れなかった理由

この時点で、React Native Item モデルと App Services App 内の対応するスキーマは一致しなくなります。それで問題ありません。

Realm オブジェクトにプロパティを追加しても重大な変更ではないため、クライアントをリセットする必要はありません。 テンプレート アプリでは開発モードが有効になっているため、クライアント Realm オブジェクトへの変更はサーバー側のスキーマに反映されます。 詳しくは、「開発モードデータモデルの更新 」を参照してください。

3

アプリのデータ モデルには、各 Item オブジェクトに対して priority が含まれるようになりました。アプリの UI をアップデートして、新しい To Do をリストに追加するときに優先順位の値を選択できるようにしましょう。

まず、優先順位ピッカー コンポーネントを実装するための外部ライブラリをインストールします。プロジェクト ルート内のターミナルで次のコマンドを実行します。

npm install @react-native-picker/picker

iOS 用にビルドしている場合は、パッケージをインストールした後、関連付けられている Cocoapods をリンクしてください。

npx pod-install

Tip

インストール後にアプリを再ビルドする必要がある場合があります。これを行うには、プロジェクトのバンドラーを停止し、ビルド コマンドを実行します。

npm run ios
npm run android

パッケージが完全にインストールされたので、ピッカーを使用するように新しい To-Do 作成プロンプトコンポーネントを更新しましょう。

source/CreateToDoPrompt.tsx の先頭に次のインポートを追加します。

import {Picker} from '@react-native-picker/picker';
import {Priority} from './ItemSchema';

次に、 CreateToDoPrompt コンポーネントを変更します。

  • onSubmit() props の定義に priority を追加する

  • 状態フックで priority を追跡する

  • インポートした Picker コンポーネントに状態を接続する

  • priorityonSubmit() ハンドラに渡す

source/CreateToDoPrompt.tsx
type Props = {
onSubmit(args: {summary: string; priority: string;}): void;
};
export function CreateToDoPrompt(props: Props): React.ReactElement<Props> {
const {onSubmit} = props;
const [summary, setSummary] = useState('');
const [priority, setPriority] = useState(Priority.High);
return (
<View style={styles.modalWrapper}>
<Text h4 style={styles.addItemTitle}>
Add To-Do Item
</Text>
<Input
placeholder="What do you want to do?"
onChangeText={(text: string) => setSummary(text)}
autoCompleteType={undefined}
/>
<Picker
style={{width: '80%'}}
selectedValue={priority}
onValueChange={value => setPriority(value)}>
{Priority.map(priority => (
<Picker.Item
key={priority}
label={priority}
value={Priority[priority]}
/>
))}
</Picker>
<Button
title="Save"
buttonStyle={styles.saveButton}
onPress={() => onSubmit({summary, priority})}
/>
</View>
);
}

source/ItemListView.tsx で、 createItem() 関数を変更して priority を受け入れて使用します。

source/ItemListView.tsx
const createItem = useCallback(
({summary, priority}: {summary: string, priority: string}) => {
realm.write(() => {
return new Item(realm, {
summary,
owner_id: user?.id,
priority
});
});
},
[realm, user],
);

次に、ToDo 送信ハンドラーの作成を変更して、 priority レベルを受け入れ、それを createItem() に渡します。

source/ItemListView.tsx
<CreateToDoPrompt
onSubmit={({summary, priority}) => {
setShowNewItemOverlay(false);
createItem({summary, priority});
}}
/>

最後に、リストアイテムテンプレートを変更して、ToDo の prioritysummary の前にレンダリングします。

source/ItemListView.tsx
<ListItem
key={`${item._id}`}
bottomDivider
topDivider
hasTVPreferredFocus={undefined}
tvParallaxProperties={undefined}>
<Text>{item.priority}</Text>
<ListItem.Title style={styles.itemTitle}>
{item.summary}
</ListItem.Title>
<ListItem.Subtitle style={styles.itemSubtitle}>
{item.owner_id === user?.id ? '(mine)' : ''}
</ListItem.Subtitle>
<ListItem.CheckBox
checked={item.isComplete}
checkedColor={COLORS.primary}
iconType="material"
checkedIcon="check-box"
uncheckedIcon="check-box-outline-blank"
onPress={() => toggleItemIsComplete(item._id)}
/>
<Button
type="clear"
onPress={() => deleteItem(item._id)}
icon={
<Icon
type="material"
name="clear"
size={12}
color="#979797"
tvParallaxProperties={undefined}
/>
}
/>
</ListItem>
4

これで、アプリでユーザーが新しい ToDo アイテムの優先順位を設定できるようになります。

アプリを再ビルドして開きます。いくつかの新しい ToDo アイテムを追加して、優先順位レベルを選択できること、およびリストに各 ToDo の優先順位が表示されることを確認します。

デバイス同期プロトコルは、各同期クライアントが標準の RQL クエリを使用してアプリケーション データのサブセットを選択し、そのサブセットに サブスクライブ する柔軟なモデルを使用します。これにより、サブセット内のすべてのデータの最新バージョンが自動的にデバイスに取得され、データの変更がデバイス間で同期されます。

たとえば、使用しているテンプレート アプリには、現在のユーザーが所有するアイテムに対する次の組み込みサブスクリプションがあります。

source/ItemListView.tsx
realm.subscriptions.update(mutableSubs => {
mutableSubs.removeByName(itemSubscriptionName);
mutableSubs.add(
realm.objects(Item).filtered(`owner_id == "${user?.id}"`),
{name: ownItemsSubscriptionName},
);
});

アプリが必要とするデータのみを同期するように、実行時にサブスクリプションをカスタマイズできます。その方法を表示する機能を追加しましょう。

このチュートリアルでは、2 つのモードを切り替えることができるボタンを追加します。1 つはアプリがすべての ToDo アイテムを同期するモード、もう 1 つはpriorityが「高」または「重大」の重要なアイテムのみを同期するモードです。

1

まず、現在のモードを追跡するために、 ItemListView コンポーネントに useState() フックを追加します。

ItemListView.tsx
const [showImportantOnly, setShowImportantOnly] = useState(false);

次に、ToDo リストの一番下、 <ListItem> の後にモードを切り替える新しいボタンを追加します。

source/ItemListView.tsx
<Button
title={showImportantOnly ? 'Show All' : 'Show Important Only'}
buttonStyle={{
...styles.addToDoButton,
backgroundColor: showImportantOnly ? '#00A35C' : '#FFC010',
}}
onPress={() => setShowImportantOnly(showImportantOnly => !showImportantOnly)}
/>
2

この点で、アプリは UI でモードを切り替えることができますが、他に何もしていないため、モードは機能的に同じです。現在のモードに関連するデータのみを同期するようにサブスクリプションをアップデートしましょう。

ItemListView コンポーネントの最初の useEffect に、現在のモードをチェックし、showImportantOnly モードがアクティブな場合はクエリに priority フィルターを付け加えるコードを追加します。

source/ItemListView.tsx
useEffect(() => {
if (showAllItems) {
realm.subscriptions.update(mutableSubs => {
mutableSubs.removeByName(ownItemsSubscriptionName);
mutableSubs.add(realm.objects(Item), {name: itemSubscriptionName});
});
} else if (showImportantOnly) {
realm.subscriptions.update(mutableSubs => {
mutableSubs.removeByName(itemSubscriptionName);
mutableSubs.add(
realm.objects(Item).filtered(`owner_id == "${user?.id}" && priority <= 1`),
{name: ownItemsSubscriptionName},
);
});
} else {
realm.subscriptions.update(mutableSubs => {
mutableSubs.removeByName(itemSubscriptionName);
mutableSubs.add(
realm.objects(Item).filtered(`owner_id == "${user?.id}"`),
{name: ownItemsSubscriptionName},
);
});
}
}, [realm, user, showAllItems, showImportantOnly]);

重要

useEffect の 2 番目の引数の依存関係のリストに showImportantOnly を追加することを忘れないでください。

3

これで、アプリは現在のモードに基づいて同期サブスクリプションを変更するように設定されました。

アプリを再構築して実行し、すべてが動作することを確認します。ToDo アイテムを作成、完了、削除できるほか、すべてのアイテムの表示と重要なアイテムのみの表示を切り替えることもできます。

Tip

開発者モードが有効になっている場合にサブスクリプションを変更する

このチュートリアルでは、サブスクリプションを変更し、優先順位フィールドを初めてクエリすると、フィールドは Device Sync Collection Queryable Fieldsに自動的に追加されます。 これは、テンプレート アプリで開発モードがデフォルトで有効になっているために発生します。 開発モードが有効になっていない場合、クライアント側の同期クエリで使用するには、フィールドをクエリ可能なフィールドとして手動で追加する必要があります。

詳細については、「クエリ可能なフィールド 」を参照してください。

注意

フィードバックの共有

ではどのようにGoしましたか。 ページ右下にあるRate this pageウィジェットを使用して、有効性を評価します。 またはGithub リポジトリ に問題を報告する 問題が発生した場合は、。

次へ

Atlas アプリケーション サービスとは