メインコンテンツまでスキップ

データの追加

楽観的更新(optimistic updates)により、高速でレスポンスの良いユーザー体験を実現します。

Mutations を使用する理由

データベース内に新しいレコードを作成したり、既存のレコードを更新したりする必要があります。Squid Client SDK は insert と update の操作を提供しており、クライアント側で変更を楽観的に適用して UI に即時フィードバックを返し、その後サーバーと非同期に同期します。

クイックスタート

Client code
// Insert a new document
await squid.collection<User>('users').doc('user_1').insert({
name: 'Alice',
email: 'alice@example.com',
});

概要

transaction 内で実行されている場合を除き、すべての insert と update は Promise を返し、サーバー上で mutation が適用されると解決(resolve)します。

insert と update はローカルで楽観的に適用され、クライアント上に即座に反映されます。その後、整合性がありクリーンなデータ状態を確保するために、変更がサーバーへ非同期に送信されます。

書き込み mutation には insertupdatesetInPath の 3 種類があります。いずれも document reference に対して実行します。

コアコンセプト

Insert

Insert は新しい document を作成するために使用します。 collection に新しい document を insert するには、DocumentReference に対して insert メソッドを呼び出し、 引数として新しい document データを渡します。

Client code
try {
await squid.collection<User>('users').doc('new_user_id').insert({
name: 'John Doe',
email: 'johndoe@example.com',
});
console.log('User added successfully');
} catch (error) {
console.error(`Failed to add user ${error}`);
}
Tip

バックエンドの security rules により、各 mutation を誰が実行できるかを粒度細かく制御できます。これらのルールは MutationContext をパラメータとして受け取り、変更前後の document のスナップショットを含む、mutation に関する必要な情報がすべて入っています。security rules の詳細を読み、書き方を理解してください。

Insert many

insertMany メソッドは、複数の document を一度に効率よく insert および/または update するために使用します。次の例では、新しいユーザー document の配列を追加します。

Client code
const newDocuments = [
{
id: 'new_user_id1',
data: {
name: 'John Doe',
email: 'johndoe@example.com',
},
},
{
id: 'new_user_id2',
data: {
name: 'Jan Smith',
email: 'jansmith@example.com',
},
},
];

try {
await squid.collection<User>('users').insertMany(newDocuments);
console.log('Users added successfully');
} catch (error) {
console.error(`Failed to add users ${error}`);
}

Update

document を update するには、DocumentReference に対して update メソッドを呼び出し、 部分更新データを含むオブジェクトを引数として渡します。

Client code
try {
await squid
.collection<User>('users')
.doc('existing_user_id')
.update({ email: 'new_email@example.com' });
console.log('User updated successfully');
} catch (error) {
console.error(`Failed to update user ${error}`);
}

Set in Path

DocumentReference に対して setInPath メソッドを呼び出し、プロパティへの path と新しい値を引数として渡すことで、document の特定のプロパティだけを update することもできます。path にはドット記法を使ってネストされたプロパティを指定します。

Client code
const userRef = squid.collection<User>('users').doc('existing_user_id');

try {
await userRef.setInPath('address.street', 'Main');
console.log('Updated successfully');
} catch (error) {
console.error(`Failed to update user ${error}`);
}

エラーハンドリング

ErrorCauseSolution
Security rule rejectionmutation が security rules によりブロックされたユーザーがその collection に対する書き込み権限を持つことを確認する
Document already exists一部の connector type で、すでに存在する document ID に対して insert を呼び出した既存 document には update を使う、または一意の ID を使用する
Invalid data shapeinsert したデータが collection schema に一致しないデータオブジェクトが期待される schema と型に一致することを確認する
Network errormutation の確認のためにサーバーへ到達できなかった楽観的更新はロールバックされるため、操作をリトライする

ベストプラクティス

  1. 部分的な変更には update() を使用する:document 全体を再 insert するのではなく、変更されたフィールドのみを送信します。

  2. 深いネストの更新には setInPath() を使用する:document の他の部分に触れずに、ネストされた単一フィールドだけを変更できます。

    Client code
    // Update only the city without affecting other address fields
    await userRef.setInPath('address.city', 'New York');
  3. バルク操作には insertMany() を使用する:サーバーとの往復回数(round trips)を減らします。

  4. 複数 document にまたがる原子性(atomicity)が必要な場合は、関連する mutation を transaction でラップする

  5. mutation のエラーを処理する:クライアント側のバリデーションを通っても、security rules や schema チェックでサーバー側が変更を拒否する場合があります。