or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

data-types.mddatabase-operations.mdindex.mdmodular-api.mdoffline-network.mdquerying-filtering.mdrealtime-sync.mdtransactions-batches.md

querying-filtering.mddocs/

0

# Querying & Filtering

1

2

Advanced query capabilities with filtering, ordering, pagination, and aggregation. Supports both simple field queries and complex composite filters.

3

4

## Capabilities

5

6

### Basic Query Operations

7

8

Execute queries to retrieve documents with optional source specification.

9

10

```typescript { .api }

11

interface Query<T = FirebaseFirestoreTypes.DocumentData> {

12

/**

13

* Execute the query and get results

14

* @param options - Optional get options to specify data source

15

* @returns Promise resolving to query snapshot

16

*/

17

get(options?: FirebaseFirestoreTypes.GetOptions): Promise<FirebaseFirestoreTypes.QuerySnapshot<T>>;

18

19

/**

20

* Check if two queries are equal

21

* @param other - Other query to compare

22

* @returns True if queries are equal

23

*/

24

isEqual(other: FirebaseFirestoreTypes.Query): boolean;

25

}

26

27

interface QuerySnapshot<T = FirebaseFirestoreTypes.DocumentData> {

28

readonly docs: FirebaseFirestoreTypes.QueryDocumentSnapshot<T>[];

29

readonly empty: boolean;

30

readonly metadata: FirebaseFirestoreTypes.SnapshotMetadata;

31

readonly query: FirebaseFirestoreTypes.Query<T>;

32

readonly size: number;

33

34

/**

35

* Get array of document changes since last snapshot

36

* @param options - Optional listen options

37

* @returns Array of document changes

38

*/

39

docChanges(options?: FirebaseFirestoreTypes.SnapshotListenOptions): FirebaseFirestoreTypes.DocumentChange<T>[];

40

41

/**

42

* Iterate over all documents in the snapshot

43

* @param callback - Function to call for each document

44

* @param thisArg - Optional this context

45

*/

46

forEach(callback: (result: FirebaseFirestoreTypes.QueryDocumentSnapshot<T>) => void, thisArg?: any): void;

47

}

48

```

49

50

**Usage Examples:**

51

52

```typescript

53

import firestore from '@react-native-firebase/firestore';

54

55

// Execute basic query

56

const snapshot = await firestore().collection('users').get();

57

58

// Process results

59

snapshot.forEach(doc => {

60

console.log(doc.id, '=>', doc.data());

61

});

62

63

// Check if query returned results

64

if (!snapshot.empty) {

65

console.log(`Found ${snapshot.size} users`);

66

}

67

68

// Get from specific source

69

const serverSnapshot = await firestore()

70

.collection('users')

71

.get({ source: 'server' });

72

```

73

74

### Where Clauses

75

76

Filter documents based on field values using various comparison operators.

77

78

```typescript { .api }

79

/**

80

* Filter query results based on field values

81

* @param fieldPath - Field to filter on (string or FieldPath)

82

* @param opStr - Comparison operator

83

* @param value - Value to compare against

84

* @returns New query with filter applied

85

*/

86

where(fieldPath: keyof T | FirebaseFirestoreTypes.FieldPath, opStr: FirebaseFirestoreTypes.WhereFilterOp, value: any): FirebaseFirestoreTypes.Query<T>;

87

88

/**

89

* Apply a filter constraint to the query

90

* @param filter - Query filter constraint

91

* @returns New query with filter applied

92

*/

93

where(filter: FirebaseFirestoreTypes.QueryFilterConstraint): FirebaseFirestoreTypes.Query<T>;

94

95

type WhereFilterOp =

96

| '<' | '<=' | '==' | '>' | '>=' | '!='

97

| 'array-contains' | 'array-contains-any'

98

| 'in' | 'not-in';

99

```

100

101

**Usage Examples:**

102

103

```typescript

104

import firestore from '@react-native-firebase/firestore';

105

106

// Equal comparison

107

const activeUsers = await firestore()

108

.collection('users')

109

.where('active', '==', true)

110

.get();

111

112

// Numeric comparisons

113

const adultsQuery = firestore()

114

.collection('users')

115

.where('age', '>=', 18);

116

117

// Array operations

118

const moderatorsQuery = firestore()

119

.collection('users')

120

.where('roles', 'array-contains', 'moderator');

121

122

// In operator for multiple values

123

const specificUsersQuery = firestore()

124

.collection('users')

125

.where('userId', 'in', ['user1', 'user2', 'user3']);

126

127

// Not equal (requires composite index)

128

const nonAdminQuery = firestore()

129

.collection('users')

130

.where('role', '!=', 'admin');

131

132

// Using FieldPath for nested fields

133

const verifiedEmailQuery = firestore()

134

.collection('users')

135

.where(new firestore.FieldPath('profile', 'emailVerified'), '==', true);

136

137

// Chain multiple where clauses

138

const queryResults = await firestore()

139

.collection('users')

140

.where('active', '==', true)

141

.where('age', '>=', 18)

142

.where('city', '==', 'New York')

143

.get();

144

```

145

146

### Composite Filters

147

148

Combine multiple filter conditions using AND/OR logic.

149

150

```typescript { .api }

151

/**

152

* Create field filter constraint

153

* @param fieldPath - Field to filter on

154

* @param operator - Comparison operator

155

* @param value - Value to compare against

156

* @returns Query field filter constraint

157

*/

158

Filter(fieldPath: keyof T | FirebaseFirestoreTypes.FieldPath, operator: FirebaseFirestoreTypes.WhereFilterOp, value: any): FirebaseFirestoreTypes.QueryFieldFilterConstraint;

159

160

/**

161

* Combine filter constraints with AND logic

162

* @param queries - Filter constraints to combine

163

* @returns Composite AND filter constraint

164

*/

165

Filter.and(...queries: FirebaseFirestoreTypes.QueryFilterConstraint[]): FirebaseFirestoreTypes.QueryCompositeFilterConstraint;

166

167

/**

168

* Combine filter constraints with OR logic

169

* @param queries - Filter constraints to combine

170

* @returns Composite OR filter constraint

171

*/

172

Filter.or(...queries: FirebaseFirestoreTypes.QueryFilterConstraint[]): FirebaseFirestoreTypes.QueryCompositeFilterConstraint;

173

```

174

175

**Usage Examples:**

176

177

```typescript

178

import firestore, { Filter } from '@react-native-firebase/firestore';

179

180

// OR filter - users who are either admin or moderator

181

const adminOrModeratorQuery = firestore()

182

.collection('users')

183

.where(

184

Filter.or(

185

Filter('role', '==', 'admin'),

186

Filter('role', '==', 'moderator')

187

)

188

);

189

190

// AND filter - active users in New York

191

const activeNYUsersQuery = firestore()

192

.collection('users')

193

.where(

194

Filter.and(

195

Filter('active', '==', true),

196

Filter('city', '==', 'New York')

197

)

198

);

199

200

// Complex nested filters - (admin OR moderator) AND active

201

const complexQuery = firestore()

202

.collection('users')

203

.where(

204

Filter.and(

205

Filter.or(

206

Filter('role', '==', 'admin'),

207

Filter('role', '==', 'moderator')

208

),

209

Filter('active', '==', true)

210

)

211

);

212

```

213

214

### Ordering

215

216

Sort query results by one or more fields in ascending or descending order.

217

218

```typescript { .api }

219

/**

220

* Order query results by a field

221

* @param fieldPath - Field to order by (string or FieldPath)

222

* @param directionStr - Sort direction ('asc' or 'desc')

223

* @returns New query with ordering applied

224

*/

225

orderBy(fieldPath: keyof T | string | FirebaseFirestoreTypes.FieldPath, directionStr?: 'asc' | 'desc'): FirebaseFirestoreTypes.Query<T>;

226

```

227

228

**Usage Examples:**

229

230

```typescript

231

import firestore from '@react-native-firebase/firestore';

232

233

// Order by creation date (ascending by default)

234

const chronologicalQuery = firestore()

235

.collection('posts')

236

.orderBy('createdAt');

237

238

// Order by creation date descending (most recent first)

239

const recentPostsQuery = firestore()

240

.collection('posts')

241

.orderBy('createdAt', 'desc');

242

243

// Multiple ordering criteria

244

const sortedUsersQuery = firestore()

245

.collection('users')

246

.orderBy('lastName')

247

.orderBy('firstName')

248

.orderBy('createdAt', 'desc');

249

250

// Order by nested field

251

const sortedByProfileQuery = firestore()

252

.collection('users')

253

.orderBy(new firestore.FieldPath('profile', 'displayName'));

254

255

// Combine with filtering (requires composite index)

256

const filteredAndSortedQuery = await firestore()

257

.collection('users')

258

.where('active', '==', true)

259

.orderBy('lastLoginAt', 'desc')

260

.get();

261

```

262

263

### Pagination

264

265

Limit result sets and implement cursor-based pagination for large datasets.

266

267

```typescript { .api }

268

/**

269

* Limit the number of documents returned

270

* @param limit - Maximum number of documents to return

271

* @returns New query with limit applied

272

*/

273

limit(limit: number): FirebaseFirestoreTypes.Query<T>;

274

275

/**

276

* Limit to last N documents (requires orderBy)

277

* @param limitToLast - Number of documents from the end

278

* @returns New query with limit applied

279

*/

280

limitToLast(limitToLast: number): FirebaseFirestoreTypes.Query<T>;

281

282

/**

283

* Start results at a document snapshot

284

* @param snapshot - Document snapshot to start at

285

* @returns New query with cursor applied

286

*/

287

startAt(snapshot: FirebaseFirestoreTypes.DocumentSnapshot<T>): FirebaseFirestoreTypes.Query<T>;

288

289

/**

290

* Start results at field values

291

* @param fieldValues - Field values to start at

292

* @returns New query with cursor applied

293

*/

294

startAt(...fieldValues: any[]): FirebaseFirestoreTypes.Query<T>;

295

296

/**

297

* Start results after a document snapshot

298

* @param snapshot - Document snapshot to start after

299

* @returns New query with cursor applied

300

*/

301

startAfter(snapshot: FirebaseFirestoreTypes.DocumentSnapshot<T>): FirebaseFirestoreTypes.Query<T>;

302

303

/**

304

* Start results after field values

305

* @param fieldValues - Field values to start after

306

* @returns New query with cursor applied

307

*/

308

startAfter(...fieldValues: any[]): FirebaseFirestoreTypes.Query<T>;

309

310

/**

311

* End results at a document snapshot

312

* @param snapshot - Document snapshot to end at

313

* @returns New query with cursor applied

314

*/

315

endAt(snapshot: FirebaseFirestoreTypes.DocumentSnapshot<T>): FirebaseFirestoreTypes.Query<T>;

316

317

/**

318

* End results at field values

319

* @param fieldValues - Field values to end at

320

* @returns New query with cursor applied

321

*/

322

endAt(...fieldValues: any[]): FirebaseFirestoreTypes.Query<T>;

323

324

/**

325

* End results before a document snapshot

326

* @param snapshot - Document snapshot to end before

327

* @returns New query with cursor applied

328

*/

329

endBefore(snapshot: FirebaseFirestoreTypes.DocumentSnapshot<T>): FirebaseFirestoreTypes.Query<T>;

330

331

/**

332

* End results before field values

333

* @param fieldValues - Field values to end before

334

* @returns New query with cursor applied

335

*/

336

endBefore(...fieldValues: any[]): FirebaseFirestoreTypes.Query<T>;

337

```

338

339

**Usage Examples:**

340

341

```typescript

342

import firestore from '@react-native-firebase/firestore';

343

344

// Basic pagination - first page

345

const firstPageQuery = firestore()

346

.collection('posts')

347

.orderBy('createdAt', 'desc')

348

.limit(10);

349

350

const firstPage = await firstPageQuery.get();

351

352

// Next page using last document as cursor

353

if (!firstPage.empty) {

354

const lastDoc = firstPage.docs[firstPage.docs.length - 1];

355

356

const nextPageQuery = firestore()

357

.collection('posts')

358

.orderBy('createdAt', 'desc')

359

.startAfter(lastDoc)

360

.limit(10);

361

362

const nextPage = await nextPageQuery.get();

363

}

364

365

// Get last N documents

366

const lastPostsQuery = firestore()

367

.collection('posts')

368

.orderBy('createdAt')

369

.limitToLast(5);

370

371

// Pagination with field values

372

const postsAfterDateQuery = firestore()

373

.collection('posts')

374

.orderBy('createdAt')

375

.startAfter(new Date('2023-01-01'))

376

.limit(10);

377

378

// Range queries using cursors

379

const specificRangeQuery = firestore()

380

.collection('users')

381

.orderBy('age')

382

.startAt(18)

383

.endBefore(65)

384

.limit(50);

385

```

386

387

### Aggregation Queries

388

389

Perform server-side aggregations like counting documents without downloading all data.

390

391

```typescript { .api }

392

/**

393

* Count the number of documents in the query

394

* @returns Aggregate query for counting documents

395

*/

396

count(): FirebaseFirestoreTypes.AggregateQuery<{ count: FirebaseFirestoreTypes.AggregateField<number> }>;

397

398

/**

399

* Count the number of documents on the server

400

* @returns Aggregate query for server-side counting

401

*/

402

countFromServer(): FirebaseFirestoreTypes.AggregateQuery<{ count: FirebaseFirestoreTypes.AggregateField<number> }>;

403

404

interface AggregateQuery<T> {

405

/**

406

* Execute the aggregate query

407

* @returns Promise resolving to aggregate query snapshot

408

*/

409

get(): Promise<FirebaseFirestoreTypes.AggregateQuerySnapshot<T>>;

410

}

411

412

interface AggregateQuerySnapshot<T> {

413

/**

414

* Get aggregate data

415

* @returns Aggregate data object

416

*/

417

data(): T;

418

}

419

```

420

421

**Usage Examples:**

422

423

```typescript

424

import firestore from '@react-native-firebase/firestore';

425

426

// Count all users

427

const allUsersCount = await firestore()

428

.collection('users')

429

.count()

430

.get();

431

432

console.log('Total users:', allUsersCount.data().count);

433

434

// Count with filters

435

const activeUsersCount = await firestore()

436

.collection('users')

437

.where('active', '==', true)

438

.count()

439

.get();

440

441

console.log('Active users:', activeUsersCount.data().count);

442

443

// Server-side counting (bypasses cache)

444

const serverCount = await firestore()

445

.collection('posts')

446

.where('published', '==', true)

447

.countFromServer()

448

.get();

449

450

console.log('Published posts:', serverCount.data().count);

451

```

452

453

## Types

454

455

```typescript { .api }

456

interface DocumentChange<T = FirebaseFirestoreTypes.DocumentData> {

457

readonly doc: FirebaseFirestoreTypes.QueryDocumentSnapshot<T>;

458

readonly newIndex: number;

459

readonly oldIndex: number;

460

readonly type: FirebaseFirestoreTypes.DocumentChangeType;

461

}

462

463

type DocumentChangeType = 'added' | 'removed' | 'modified';

464

465

interface QueryDocumentSnapshot<T = FirebaseFirestoreTypes.DocumentData> extends DocumentSnapshot<T> {

466

/**

467

* QueryDocumentSnapshot always contains data (exists is always true)

468

*/

469

data(options?: FirebaseFirestoreTypes.SnapshotOptions): T;

470

}

471

472

interface AggregateField<T> {

473

/**

474

* Get the aggregate field value

475

* @returns The aggregated value

476

*/

477

value(): T;

478

}

479

```