@@ -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
- StringmakeUrl (const String& path,const String& auth) {
22
+ StringmakeFirebaseURL (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
- StringerrorMessage ()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
- StringrawResponse ();
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
- FirebaseGetResultFirebase::get (const String& path) {
80
- FirebaseCallcall (host_, auth_," GET" , path, &http_);
81
- return call.isError () ?FirebaseGetResult::FromError (call.errorMessage ())
82
- :FirebaseGetResult::FromResponse (call.rawResponse ());
45
+ FirebaseGetFirebase::get (const String& path) {
46
+ return FirebaseGet (host_, auth_, path, &http_);
83
47
}
84
48
85
- FirebasePushResultFirebase::push (const String& path,const String& value) {
86
- FirebaseCallcall (host_, auth_," POST" , path, value, &http_);
87
- return call.isError () ?FirebasePushResult::FromError (call.errorMessage ())
88
- :FirebasePushResult::FromResponse (call.rawResponse ());
49
+ FirebasePushFirebase::push (const String& path,const String& value) {
50
+ return FirebasePush (host_, auth_, path, value, &http_);
89
51
}
90
52
91
- FirebaseRemoveResultFirebase::remove (const String& path) {
92
- FirebaseCallcall (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
+ FirebaseRemoveFirebase::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
- StringFirebaseCall::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 ::EventFirebaseEventStream ::read (String& event) {
149
+ FirebaseStream ::EventFirebaseStream ::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
- StringFirebaseEventStream::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
-