@@ -19,7 +19,7 @@ namespace {
19
19
const char * kFirebaseFingerprint = " 7A 54 06 9B DC 7A 25 B3 86 8D 66 53 48 2C 0B 96 42 C7 B3 0A" ;
20
20
const uint16_t kFirebasePort = 443 ;
21
21
22
- String makeUrl (const String& path, const String& auth) {
22
+ String makeFirebaseURL (const String& path, const String& auth) {
23
23
String url;
24
24
if (path[0 ] != ' /' ) {
25
25
url = " /" ;
@@ -31,40 +31,6 @@ String makeUrl(const String& path, const String& auth) {
31
31
return url;
32
32
}
33
33
34
- class FirebaseCall {
35
- public:
36
- FirebaseCall (const String& host, const String& auth,
37
- const char * method, const String& path, const String& value,
38
- HTTPClient* http);
39
- FirebaseCall (const String& host, const String& auth,
40
- const char * method, const String& path,
41
- HTTPClient* http);
42
-
43
-
44
- // True if there was an error completing call.
45
- bool isError () const ;
46
- String errorMessage () const ;
47
-
48
- // True if http status code is 200(OK).
49
- bool isOk () const ;
50
-
51
- // Message sent back from Firebase backend. This pulls value to local memory,
52
- // be careful if value can be large.
53
- String rawResponse ();
54
-
55
- int httpStatus () const {
56
- return status_;
57
- }
58
-
59
- private:
60
- FirebaseCall (HTTPClient* http);
61
-
62
- HTTPClient* http_;
63
-
64
- int status_;
65
- String error_message_;
66
- };
67
-
68
34
} // namespace
69
35
70
36
Firebase::Firebase (const String& host) : host_(host) {
@@ -76,180 +42,122 @@ Firebase& Firebase::auth(const String& auth) {
76
42
return *this ;
77
43
}
78
44
79
- FirebaseGetResult Firebase::get (const String& path) {
80
- FirebaseCall call (host_, auth_, " GET" , path, &http_);
81
- return call.isError () ? FirebaseGetResult::FromError (call.errorMessage ())
82
- : FirebaseGetResult::FromResponse (call.rawResponse ());
45
+ FirebaseGet Firebase::get (const String& path) {
46
+ return FirebaseGet (host_, auth_, path, &http_);
83
47
}
84
48
85
- FirebasePushResult Firebase::push (const String& path, const String& value) {
86
- FirebaseCall call (host_, auth_, " POST" , path, value, &http_);
87
- return call.isError () ? FirebasePushResult::FromError (call.errorMessage ())
88
- : FirebasePushResult::FromResponse (call.rawResponse ());
49
+ FirebasePush Firebase::push (const String& path, const String& value) {
50
+ return FirebasePush (host_, auth_, path, value, &http_);
89
51
}
90
52
91
- FirebaseRemoveResult Firebase::remove (const String& path) {
92
- FirebaseCall call (host_, auth_, " DELETE" , path, &http_);
93
- if (call.isError ()) {
94
- return FirebaseRemoveResult::FromError (call.errorMessage ());
95
- }
96
- // Remove is only complete if returned status is OK(200).
97
- if (!call.isOk ()) {
98
- return FirebaseRemoveResult::FromError (
99
- " Remove " + path + " returned with status " + call.httpStatus ());
100
- }
101
- return FirebaseRemoveResult::Ok ();
53
+ FirebaseRemove Firebase::remove (const String& path) {
54
+ return FirebaseRemove (host_, auth_, path, &http_);
102
55
}
103
56
104
- FirebaseEventStream Firebase::stream (const String& path) {
105
- return FirebaseEventStream (host_, auth_, path);
57
+ FirebaseStream Firebase::stream (const String& path) {
58
+ return FirebaseStream (host_, auth_, path); // stream doesn't reuse http client.
106
59
}
107
60
108
- /* FirebaseCall */
61
+ // FirebaseCall
109
62
FirebaseCall::FirebaseCall (const String& host, const String& auth,
110
- const char * method, const String& path, const String& value,
111
- HTTPClient* http) : http_(http) {
112
- const String url = makeUrl (path, auth);
113
- http_->begin (host.c_str (), kFirebasePort , url.c_str (), true , kFirebaseFingerprint );
114
- status_ = http_->sendRequest (method, (uint8_t *)value.c_str (), value.length ());
115
- if (isError ()) {
116
- error_message_ = String (method) + " " + url + " : " + HTTPClient::errorToString (status_);
63
+ const char * method, const String& path,
64
+ const String& data, HTTPClient* http) {
65
+ if (!http) {
66
+ http = &http_;
117
67
}
118
- }
119
68
120
- FirebaseCall::FirebaseCall (const String& host, const String& auth,
121
- const char * method, const String& path,
122
- HTTPClient* http) : FirebaseCall(host, auth, method, path, " " , http) {
123
- }
69
+ String url = makeFirebaseURL (path, auth);
70
+ http->setReuse (true );
71
+ http->begin (host, kFirebasePort , url, true , kFirebaseFingerprint );
124
72
125
- bool FirebaseCall::isOk () const {
126
- return status_ == HTTP_CODE_OK;
127
- }
73
+ bool followRedirect = false ;
74
+ if (method == " STREAM" ) {
75
+ method = " GET" ;
76
+ http->addHeader (" Accept" , " text/event-stream" );
77
+ followRedirect = true ;
78
+ }
128
79
129
- bool FirebaseCall::isError () const {
130
- return status_ < 0 ;
131
- }
80
+ if (followRedirect) {
81
+ const char * headers[] = {" Location" };
82
+ http->collectHeaders (headers, 1 );
83
+ }
84
+
85
+ int status = http->sendRequest (method, (uint8_t *)data.c_str (), data.length ());
86
+
87
+ // TODO: Add a max redirect check
88
+ if (followRedirect) {
89
+ while (status == HTTP_CODE_TEMPORARY_REDIRECT) {
90
+ String location = http->header (" Location" );
91
+ http->setReuse (false );
92
+ http->end ();
93
+ http->setReuse (true );
94
+ http->begin (location, kFirebaseFingerprint );
95
+ status = http->sendRequest (method, (uint8_t *)NULL , 0 );
96
+ }
97
+ }
132
98
133
- String FirebaseCall::errorMessage () const {
134
- return error_message_ ;
135
- }
99
+ if (status != 200 ) {
100
+ error_ = FirebaseError (status, String (method) + " " + url + " : " + HTTPClient::errorToString (status)) ;
101
+ }
136
102
137
- String FirebaseCall::rawResponse () {
138
- return http_->getString ();
103
+ // if not streaming.
104
+ if (!followRedirect) {
105
+ response_ = http->getString ();
106
+ }
139
107
}
140
108
141
- /* FirebaseEventStream */
109
+ // FirebaseGet
110
+ FirebaseGet::FirebaseGet (const String& host, const String& auth,
111
+ const String& path,
112
+ HTTPClient* http)
113
+ : FirebaseCall(host, auth, " GET" , path, " " , http) {
142
114
143
- FirebaseEventStream::FirebaseEventStream (const String& host, const String& auth,
144
- const String& path) {
145
- const String url = makeUrl (path, auth);
146
- http_.setReuse (true );
147
- http_.begin (host.c_str (), kFirebasePort , url.c_str (), true ,
148
- kFirebaseFingerprint );
149
- const char * headers[] = {" Location" };
150
- http_.collectHeaders (headers, 1 );
151
- http_.addHeader (" Accept" , " text/event-stream" );
152
- status_ = http_.sendRequest (" GET" , (uint8_t *)NULL , 0 );
153
-
154
- String location;
155
- // TODO(proppy): Add a max redirect check
156
- while (status_ == HTTP_CODE_TEMPORARY_REDIRECT) {
157
- location = http_.header (" Location" );
158
- http_.setReuse (false );
159
- http_.end ();
160
- http_.setReuse (true );
161
- http_.begin (location, kFirebaseFingerprint );
162
- status_ = http_.sendRequest (" GET" , (uint8_t *)NULL , 0 );
115
+ if (!error ()) {
116
+ // TODO: parse json
117
+ json_ = response ();
163
118
}
119
+ }
164
120
165
- if (status_ != 200 ) {
166
- error_message_ = " stream " + location + " : "
167
- + HTTPClient::errorToString (status_);
121
+ // FirebasePush
122
+ FirebasePush::FirebasePush (const String& host, const String& auth,
123
+ const String& path, const String& value,
124
+ HTTPClient* http)
125
+ : FirebaseCall(host, auth, " POST" , path, value, http) {
126
+ if (!error ()) {
127
+ // TODO: parse name
128
+ name_ = response ();
168
129
}
169
130
}
170
131
171
- bool FirebaseEventStream::connected () {
172
- return http_.connected ();
132
+ // FirebasePush
133
+ FirebaseRemove::FirebaseRemove (const String& host, const String& auth,
134
+ const String& path,
135
+ HTTPClient* http)
136
+ : FirebaseCall(host, auth, " DELETE" , path, " " , http) {
173
137
}
174
138
175
- bool FirebaseEventStream::available () {
139
+ // FirebaseStream
140
+ FirebaseStream::FirebaseStream (const String& host, const String& auth,
141
+ const String& path)
142
+ : FirebaseCall(host, auth, " STREAM" , path) {
143
+ }
144
+
145
+ bool FirebaseStream::available () {
176
146
return http_.getStreamPtr ()->available ();
177
147
}
178
148
179
- FirebaseEventStream ::Event FirebaseEventStream ::read (String& event) {
149
+ FirebaseStream ::Event FirebaseStream ::read (String& event) {
180
150
auto client = http_.getStreamPtr ();
181
151
Event type;
182
152
String typeStr = client->readStringUntil (' \n ' ).substring (7 );
183
153
if (typeStr == " put" ) {
184
- type = FirebaseEventStream:: Event::PUT;
154
+ type = Event::PUT;
185
155
} else if (typeStr == " patch" ) {
186
- type = FirebaseEventStream:: Event::PATCH;
156
+ type = Event::PATCH;
187
157
} else {
188
- type = FirebaseEventStream:: Event::UNKNOWN;
158
+ type = Event::UNKNOWN;
189
159
}
190
160
event = client->readStringUntil (' \n ' ).substring (6 );
191
161
client->readStringUntil (' \n ' ); // consume separator
192
162
return type;
193
163
}
194
-
195
- bool FirebaseEventStream::isError () const {
196
- return status_ < 0 ;
197
- }
198
-
199
- String FirebaseEventStream::errorMessage () const {
200
- return error_message_;
201
- }
202
-
203
- FirebaseEventStream::operator bool () {
204
- return !isError () && connected ();
205
- }
206
-
207
- /* FirebaseResult */
208
-
209
- FirebaseResult::FirebaseResult (const String& error_message)
210
- : is_error_(true ), error_message_(error_message) {}
211
-
212
- FirebaseResult::FirebaseResult () {}
213
-
214
- FirebaseResult::operator bool () const {
215
- return !isError ();
216
- }
217
-
218
- bool FirebaseResult::isError () const {
219
- return is_error_;
220
- }
221
-
222
- const String& FirebaseResult::errorMessage () const {
223
- return error_message_;
224
- }
225
-
226
- /* FirebaseRemoveResult */
227
-
228
- FirebaseRemoveResult::FirebaseRemoveResult (const String& error_message)
229
- : FirebaseResult(error_message) {}
230
-
231
- FirebaseRemoveResult::FirebaseRemoveResult () {}
232
-
233
-
234
- /* FirebasePushResult */
235
-
236
- FirebasePushResult::FirebasePushResult (const String& error_message)
237
- : FirebaseResult(error_message) {}
238
-
239
- FirebasePushResult::FirebasePushResult () {}
240
-
241
- const String& FirebasePushResult::name () const {
242
- return name_;
243
- }
244
-
245
- /* FirebaseGetResult */
246
-
247
- FirebaseGetResult::FirebaseGetResult (const String& error_message)
248
- : FirebaseResult(error_message) {}
249
-
250
- FirebaseGetResult::FirebaseGetResult () {}
251
-
252
- const String& FirebaseGetResult::rawResponse () {
253
- return response_;
254
- }
255
-
0 commit comments