Skip to content

Commit 57617f1

Browse files
feat: Add Dart sample for https-time-server (#1251)
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
1 parent a6ae4cb commit 57617f1

7 files changed

Lines changed: 287 additions & 0 deletions

File tree

.github/workflows/test_dart.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Copyright 2026 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
name: CI Tests
16+
17+
on:
18+
pull_request:
19+
paths:
20+
- 'Dart/**'
21+
22+
push:
23+
branches:
24+
- main
25+
paths:
26+
- 'Dart/**'
27+
28+
env:
29+
CI: true
30+
31+
jobs:
32+
unit:
33+
runs-on: ubuntu-latest
34+
strategy:
35+
matrix:
36+
dart-version:
37+
- "3.11.4"
38+
steps:
39+
- uses: actions/checkout@v4
40+
41+
- name: Set up Dart ${{ matrix.dart-version }}
42+
uses: dart-lang/setup-dart@v1.6.0
43+
with:
44+
sdk: ${{ matrix.dart-version }}
45+
46+
- name: HTTPS Time Server - Install dependencies
47+
working-directory: ./Dart/quickstarts/https-time-server
48+
run: dart pub get
49+
50+
- name: HTTPS Time Server - Format
51+
working-directory: ./Dart/quickstarts/https-time-server
52+
run: dart format --set-exit-if-changed .
53+
54+
- name: HTTPS Time Server - Analyze
55+
working-directory: ./Dart/quickstarts/https-time-server
56+
run: dart analyze .
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: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Firebase SDK for Cloud Functions Quickstart - HTTPS trigger
2+
3+
This quickstart demonstrates using the **Firebase SDK for Cloud Functions** with an HTTPS trigger through building an endpoint returning the current time.
4+
5+
6+
## Introduction
7+
8+
The function `date` returns the current server date. You can pass it a `format` URL Query parameter to format the date.
9+
10+
Further reading:
11+
12+
- [Read more about the Firebase SDK for Cloud Functions](https://firebase.google.com/docs/functions)
13+
14+
15+
## Initial setup, build tools and dependencies
16+
17+
### 1. Clone this repo
18+
19+
Clone or download this repo and open the `Dart/quickstarts/https-time-server` directory.
20+
21+
22+
### 2. Create a Firebase project and configure the quickstart
23+
24+
Create a Firebase Project on the [Firebase Console](https://console.firebase.google.com).
25+
26+
Set up your Firebase project by running `firebase use --add`, select your Project ID and follow the instructions.
27+
28+
29+
### 3. Install the Firebase CLI and enable Functions on your Firebase CLI
30+
31+
You need to have installed the Firebase CLI. If you haven't run:
32+
33+
```bash
34+
npm install -g firebase-tools
35+
```
36+
37+
> Doesn't work? You may need to [change npm permissions](https://docs.npmjs.com/getting-started/fixing-npm-permissions).
38+
39+
40+
## Deploy the app to prod
41+
42+
First you need to get the `dart` dependencies of the functions:
43+
44+
```bash
45+
dart pub get
46+
```
47+
48+
This installs locally:
49+
- The Firebase Functions Dart SDK.
50+
- The [intl](https://pub.dev/packages/intl) pub package to format time.
51+
52+
Deploy to Firebase using the following command:
53+
54+
```bash
55+
firebase deploy
56+
```
57+
58+
This deploys and activates the date Function.
59+
60+
> The first time you call `firebase deploy` on a new project with Functions will take longer than usual.
61+
62+
63+
Alteratively, you can call `firebase emulators:start` to test the functions on the local emulator suite.
64+
65+
66+
## Try the sample
67+
68+
After deploying the function, check the CLI's output to see the URL for your function.
69+
70+
It will look something like: `https://<function-name>-<random-hash>.<region>.run.app`
71+
72+
You can also send the format in the request body. For instance using cURL in the command line:
73+
74+
```bash
75+
curl -H 'Content-Type: application/json' /
76+
-d '{"format": "MMMM d yyyy, h:mm:ss a"}' /
77+
<function url>
78+
```
79+
Formatted dates should be displayed.
80+
81+
We are responding with a 403 error in case of PUT requests:
82+
83+
```bash
84+
curl -X PUT -d '{"format": "MMMM d yyyy, h:mm:ss a"}' <function-url>
85+
```
86+
87+
88+
## Contributing
89+
90+
We'd love that you contribute to the project. Before doing so please read our [Contributor guide](../../CONTRIBUTING.md).
91+
92+
93+
## License
94+
95+
© Google, 2026. Licensed under an [Apache-2](../../../LICENSE) license.
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// Copyright 2026 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// [START dartHttpImport]
16+
import 'package:firebase_functions/firebase_functions.dart';
17+
// [END dartHttpImport]
18+
19+
// [START dartHttpAdditionalImports]
20+
import 'dart:convert';
21+
import 'package:intl/intl.dart';
22+
// [END dartHttpAdditionalImports]
23+
24+
// [START dartHttpAll]
25+
/// Returns the server's date.
26+
/// Options `timeoutSeconds` and `region` are optional.
27+
///
28+
/// You must provide a `format` URL query parameter or `format` value in
29+
/// the request body with which we'll try to format the date.
30+
///
31+
/// Format must follow the Dart intl library. See: https://pub.dev/packages/intl
32+
///
33+
/// Example format: "MMMM d yyyy, h:mm:ss a".
34+
/// Example request using URL query parameters:
35+
/// https://date-<random-hash>.<region>.run.app?format=MMMM%20d%20yyyy%2C%20h%3Amm%3Ass%20a
36+
/// Example request using request body with cURL:
37+
/// curl -H 'Content-Type: application/json' /
38+
/// -d '{"format": "MMMM d yyyy, h:mm:ss a"}' /
39+
/// https://date-<random-hash>.<region>.run.app
40+
void main(List<String> args) async {
41+
await fireUp(args, (firebase) {
42+
// [START dartHttpTrigger]
43+
firebase.https.onRequest(name: 'date', (request) async {
44+
// [END dartHttpTrigger]
45+
46+
// [START dartHttpSendError]
47+
// Forbidding PUT requests.
48+
if (request.method == 'PUT') {
49+
return Response.forbidden('Forbidden!');
50+
}
51+
// [END dartHttpSendError]
52+
53+
// Reading date format from URL query parameter.
54+
// [START dartHttpReadQueryParam]
55+
var format = request.url.queryParameters['format'];
56+
// [END dartHttpReadQueryParam]
57+
58+
// Reading date format from request body query parameter
59+
if (format == null) {
60+
// [START dartHttpReadBodyParam]
61+
final bodyString = await request.readAsString();
62+
try {
63+
if (bodyString.isNotEmpty) {
64+
final body = jsonDecode(bodyString) as Map<String, dynamic>;
65+
format = body['format'] as String?;
66+
}
67+
} catch (e) {
68+
return Response.badRequest(body: 'invalid JSON');
69+
}
70+
// [END dartHttpReadBodyParam]
71+
}
72+
73+
// Set a default format if none was provided
74+
format ??= 'MMMM d yyyy, h:mm:ss a';
75+
76+
// [START dartHttpSendResponse]
77+
final formattedDate = DateFormat(format).format(DateTime.now());
78+
print('Sending formatted date: $formattedDate');
79+
return Response.ok(formattedDate);
80+
// [END dartHttpSendResponse]
81+
});
82+
});
83+
}
84+
85+
// [END dartHttpAll]
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"functions": {
3+
"source": ".",
4+
"codebase": "dart-quickstarts-https-time-server"
5+
}
6+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: https_time_server
2+
description: HTTPS trigger examples for Firebase Functions for Dart
3+
publish_to: none
4+
5+
environment:
6+
sdk: ^3.11.0
7+
8+
dependencies:
9+
firebase_functions:
10+
git:
11+
url: https://github.com/firebase/firebase-functions-dart
12+
ref: main
13+
dart_firebase_admin:
14+
git:
15+
url: https://github.com/firebase/firebase-admin-dart
16+
path: packages/dart_firebase_admin
17+
ref: main
18+
google_cloud_firestore:
19+
git:
20+
url: https://github.com/firebase/firebase-admin-dart
21+
path: packages/google_cloud_firestore
22+
ref: main
23+
intl: ^0.20.2
24+
25+
dev_dependencies:
26+
build_runner: ^2.10.5
27+
lints: ^6.0.0
28+
29+
dependency_overrides:
30+
dart_firebase_admin:
31+
git:
32+
url: https://github.com/firebase/firebase-admin-dart
33+
path: packages/dart_firebase_admin
34+
ref: main
35+
google_cloud_firestore:
36+
git:
37+
url: https://github.com/firebase/firebase-admin-dart
38+
path: packages/google_cloud_firestore
39+
ref: main

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ This quickstart sample demonstrates using **Cloud Functions** triggered by **Fir
3737

3838
### HTTPS trigger quickstart: Time Server
3939

40+
- [Dart](/Dart/quickstarts/https-time-server/)
4041
- [Node 2nd gen](/Node/quickstarts/https-time-server/)
4142
- [Python](/Python/quickstarts/https-time-server/)
4243
- [Node 1st gen](/Node-1st-gen/quickstarts/https-time-server/)

0 commit comments

Comments
 (0)