Skip to content

Commit 2ebee4d

Browse files
Refactor Dart counter sample to use a shared package (#1267)
- Created a new `shared` package to hold `IncrementResponse` and `incrementCallable`. - Updated `https-increment-number/pubspec.yaml` to depend on the `shared` package. - Replaced `https-increment-number/bin/server.dart` with updated user code, fixing syntax errors. - Added appropriate `.gitignore` files to exclude generated Dart tooling and locks. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
1 parent 5c40153 commit 2ebee4d

File tree

5 files changed

+80
-82
lines changed

5 files changed

+80
-82
lines changed
Lines changed: 48 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,65 @@
11
import 'dart:convert';
2-
import 'package:dart_firebase_admin/dart_firebase_admin.dart';
32
import 'package:firebase_functions/firebase_functions.dart';
4-
import 'package:google_cloud_firestore/google_cloud_firestore.dart';
5-
6-
class IncrementResponse {
7-
final String message;
8-
final int newCount;
9-
10-
IncrementResponse({required this.message, required this.newCount});
11-
12-
Map<String, dynamic> toJson() => {'message': message, 'newCount': newCount};
13-
}
3+
import 'package:google_cloud_firestore/google_cloud_firestore.dart'
4+
show FieldValue;
5+
import 'package:shared/shared.dart';
146

157
void main(List<String> args) async {
168
await fireUp(args, (firebase) {
17-
// [START dartHttpIncrementLocal]
18-
firebase.https.onRequest(name: 'incrementLocal', (request) async {
19-
print('Incrementing counter locally...');
20-
21-
if (request.method != 'POST') {
22-
return Response(405, body: 'Method Not Allowed');
23-
}
24-
25-
int currentCount = 0;
26-
final bodyString = await request.readAsString();
27-
if (bodyString.isNotEmpty) {
28-
try {
29-
final body = jsonDecode(bodyString) as Map<String, dynamic>;
30-
currentCount = body['count'] as int? ?? 0;
31-
} catch (e) {
32-
return Response.badRequest(body: 'Invalid JSON request');
33-
}
34-
}
35-
36-
final response = IncrementResponse(
37-
message: 'Local increment complete!',
38-
newCount: currentCount + 1,
39-
);
40-
41-
return Response(
42-
200,
43-
body: jsonEncode(response.toJson()),
44-
headers: {'Content-Type': 'application/json'},
45-
);
46-
});
47-
// [END dartHttpIncrementLocal]
9+
// Listen for calls to the http request and name defined in the shared package.
10+
firebase.https.onRequest(name: incrementCallable, (request) async {
11+
// In a production app, verify the user with request.auth?.uid here.
12+
print('Incrementing counter on the server...');
4813

49-
// [START dartHttpIncrementSynced]
50-
firebase.https.onRequest(name: 'incrementSynced', (request) async {
51-
print('Processing synced counter request...');
52-
53-
// Get firestore admin instance
54-
final firestore = FirebaseApp.instance.firestore();
14+
// Get firestore database instance
15+
final firestore = firebase.adminApp.firestore();
5516

5617
// Get a reference to the counter document
5718
final counterDoc = firestore.collection('counters').doc('global');
5819

59-
// Fetch the current counter value
20+
// Get the current snapshot for the count data
6021
final snapshot = await counterDoc.get();
61-
final currentCount = snapshot.data()?['count'] as int? ?? 0;
62-
63-
if (request.method == 'GET') {
64-
// Handle GET request to respond with the current counter
65-
final response = IncrementResponse(
66-
message: 'Cloud-sync fetched!',
67-
newCount: currentCount,
68-
);
69-
70-
return Response(
71-
200,
72-
body: jsonEncode(response.toJson()),
73-
headers: {'Content-Type': 'application/json'},
74-
);
75-
} else if (request.method == 'POST') {
76-
// Handle POST request to increment the counter
77-
78-
// Increment count by one
79-
await counterDoc.set({
80-
'count': FieldValue.increment(1),
81-
}, options: SetOptions.merge());
82-
83-
final response = IncrementResponse(
84-
message: 'Cloud-sync complete!',
85-
newCount: currentCount + 1,
86-
);
8722

88-
return Response(
89-
200,
90-
body: jsonEncode(response.toJson()),
91-
headers: {'Content-Type': 'application/json'},
92-
);
23+
// Increment response we will send back
24+
IncrementResponse incrementResponse;
25+
26+
// Check for the current count and if the snapshot exists
27+
if (snapshot.data() case {'count': int value} when snapshot.exists) {
28+
if (request.method == 'GET') {
29+
// Get the current result
30+
incrementResponse = IncrementResponse(
31+
success: true,
32+
message: 'Read-only sync complete',
33+
newCount: value,
34+
);
35+
} else if (request.method == 'POST') {
36+
// Increment count by one
37+
final step = request.url.queryParameters['step'] as int? ?? 1;
38+
await counterDoc.update({'count': FieldValue.increment(step)});
39+
incrementResponse = IncrementResponse(
40+
success: true,
41+
message: 'Atomic increment complete',
42+
newCount: value + 1,
43+
);
44+
} else {
45+
return Response(405, body: 'Method Not Allowed');
46+
}
9347
} else {
94-
return Response(405, body: 'Method Not Allowed');
48+
// Create a new document with a count of 1
49+
await counterDoc.set({'count': 1});
50+
incrementResponse = const IncrementResponse(
51+
success: true,
52+
message: 'Cloud-sync complete',
53+
newCount: 1,
54+
);
9555
}
56+
57+
// Return the response as JSON
58+
return Response(
59+
200,
60+
body: jsonEncode(incrementResponse.toJson()),
61+
headers: {'Content-Type': 'application/json'},
62+
);
9663
});
97-
// [END dartHttpIncrementSynced]
9864
});
9965
}

Dart/quickstarts/https-increment-number/pubspec.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ environment:
66
sdk: ^3.11.0
77

88
dependencies:
9+
shared:
10+
path: ../shared
911
firebase_functions:
1012
git:
1113
url: https://github.com/firebase/firebase-functions-dart

Dart/quickstarts/shared/.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.dart_tool/
2+
.packages
3+
build/
4+
*.dart_tool
5+
pubspec.lock
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
class IncrementResponse {
2+
final bool success;
3+
final String message;
4+
final int newCount;
5+
6+
const IncrementResponse({
7+
required this.success,
8+
required this.message,
9+
required this.newCount,
10+
});
11+
12+
Map<String, dynamic> toJson() => {
13+
'success': success,
14+
'message': message,
15+
'newCount': newCount,
16+
};
17+
}
18+
19+
const String incrementCallable = 'incrementSynced';
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
name: shared
2+
description: Shared classes.
3+
publish_to: none
4+
5+
environment:
6+
sdk: ^3.11.0

0 commit comments

Comments
 (0)