16
16
17
17
#include " FirebaseArduino.h"
18
18
19
- // This is needed to compile std::string on esp8266.
20
- template class std ::basic_string<char >;
19
+ const char * kApplicationType = " application/json" ;
20
+ const uint16_t kFirebasePort = 443 ;
21
+ const int kStatusOK = 200 ;
22
+ const int kStatusTemporaryRedirect = 307 ;
23
+
24
+ String makeFirebaseURI (const String& path, const String& auth) {
25
+ String uri;
26
+ if (path[0 ] != ' /' ) {
27
+ uri = " /" ;
28
+ }
29
+ uri += path;
30
+ uri += " .json" ;
31
+ if (auth.length () > 0 ) {
32
+ uri += " ?auth=" ;
33
+ uri += auth;
34
+ }
35
+ return uri;
36
+ }
37
+
38
+ FirebaseArduino::FirebaseArduino (Client& client) : client_(client) {}
21
39
22
40
void FirebaseArduino::begin (const String& host, const String& auth) {
23
41
host_ = host.c_str ();
@@ -26,17 +44,15 @@ void FirebaseArduino::begin(const String& host, const String& auth) {
26
44
27
45
void FirebaseArduino::initStream () {
28
46
if (stream_http_.get () == nullptr ) {
29
- stream_http_.reset (FirebaseHttpClient::create ());
30
- stream_http_->setReuseConnection (true );
31
- stream_.reset (new FirebaseStream (stream_http_));
47
+ stream_http_.reset (new HttpClient (client_, host_, kFirebasePort ));
48
+ stream_http_->connectionKeepAlive ();
32
49
}
33
50
}
34
51
35
52
void FirebaseArduino::initRequest () {
36
53
if (req_http_.get () == nullptr ) {
37
- req_http_.reset (FirebaseHttpClient::create ());
38
- req_http_->setReuseConnection (true );
39
- req_.reset (new FirebaseRequest (req_http_));
54
+ req_http_.reset (new HttpClient (client_, host_, kFirebasePort ));
55
+ req_http_->connectionKeepAlive ();
40
56
}
41
57
}
42
58
@@ -62,11 +78,20 @@ String FirebaseArduino::push(const String& path, const JsonVariant& value) {
62
78
char * buf = new char [size];
63
79
value.printTo (buf, size);
64
80
initRequest ();
65
- int status = req_.get ()->sendRequest (host_, auth_, " POST" , path.c_str (), buf);
66
- error_ = req_.get ()->error ();
67
- const char * name = req_.get ()->json ()[" name" ].as <const char *>();
81
+ String uri = makeFirebaseURI (path, auth_);
82
+ int err = req_http_->post (uri.c_str (), kApplicationType , buf);
83
+ if (err != 0 ) {
84
+ error_ = FirebaseError (err, " HTTP request failed" );
85
+ return " " ;
86
+ }
87
+ int statusCode = req_http_->responseStatusCode ();
88
+ if (statusCode != kStatusOK ) {
89
+ error_ = FirebaseError (statusCode, " PUT request failed" );
90
+ return " " ;
91
+ }
68
92
delete buf;
69
- return name;
93
+ StaticJsonBuffer<FIREBASE_JSONBUFFER_SIZE> jsonBuffer;
94
+ return jsonBuffer.parseObject (req_http_->responseBody ())[" name" ];
70
95
}
71
96
72
97
void FirebaseArduino::setInt (const String& path, int value) {
@@ -91,31 +116,50 @@ void FirebaseArduino::set(const String& path, const JsonVariant& value) {
91
116
char * buf= new char [size];
92
117
value.printTo (buf, size);
93
118
initRequest ();
94
- req_.get ()->sendRequest (host_, auth_, " PUT" , path.c_str (), buf);
95
- error_ = req_.get ()->error ();
119
+ String uri = makeFirebaseURI (path, auth_);
120
+ int err = req_http_->put (uri.c_str (), kApplicationType , buf);
121
+ if (err != 0 ) {
122
+ error_ = FirebaseError (err, " HTTP request failed" );
123
+ return ;
124
+ }
125
+ int statusCode = req_http_->responseStatusCode ();
126
+ if (statusCode != kStatusOK ) {
127
+ error_ = FirebaseError (statusCode, " POST request failed" );
128
+ return ;
129
+ }
130
+ req_http_->responseBody (); // consume body;
96
131
delete buf;
97
132
}
98
133
99
134
void FirebaseArduino::getRequest (const String& path) {
100
135
initRequest ();
101
- req_.get ()->sendRequest (host_, auth_, " GET" , path.c_str ());
102
- error_ = req_.get ()->error ();
136
+ String uri = makeFirebaseURI (path, auth_);
137
+ int err = req_http_->get (uri.c_str ());
138
+ if (err != 0 ) {
139
+ error_ = FirebaseError (err, " HTTP request failed" );
140
+ return ;
141
+ }
142
+ int statusCode = req_http_->responseStatusCode ();
143
+ if (statusCode != kStatusOK ) {
144
+ error_ = FirebaseError (err, " GET request failed" );
145
+ return ;
146
+ }
103
147
}
104
148
105
149
FirebaseObject FirebaseArduino::get (const String& path) {
106
150
getRequest (path);
107
151
if (failed ()) {
108
152
return FirebaseObject{" " };
109
153
}
110
- return FirebaseObject (req_. get ()-> response (). c_str ());
154
+ return FirebaseObject (req_http_-> responseBody ());
111
155
}
112
156
113
157
int FirebaseArduino::getInt (const String& path) {
114
158
getRequest (path);
115
159
if (failed ()) {
116
160
return 0 ;
117
161
}
118
- return FirebaseObject (req_. get ()-> response (). c_str ()).getInt ();
162
+ return FirebaseObject (req_http_-> responseBody ()).getInt ();
119
163
}
120
164
121
165
@@ -124,56 +168,88 @@ float FirebaseArduino::getFloat(const String& path) {
124
168
if (failed ()) {
125
169
return 0 .0f ;
126
170
}
127
- return FirebaseObject (req_. get ()-> response (). c_str ()).getFloat ();
171
+ return FirebaseObject (req_http_-> responseBody ()).getFloat ();
128
172
}
129
173
130
174
String FirebaseArduino::getString (const String& path) {
131
175
getRequest (path);
132
176
if (failed ()) {
133
177
return " " ;
134
178
}
135
- return FirebaseObject (req_. get ()-> response (). c_str ()).getString ();
179
+ return FirebaseObject (req_http_-> responseBody ()).getString ();
136
180
}
137
181
138
182
bool FirebaseArduino::getBool (const String& path) {
139
183
getRequest (path);
140
184
if (failed ()) {
141
185
return " " ;
142
186
}
143
- return FirebaseObject (req_. get ()-> response (). c_str ()).getBool ();
187
+ return FirebaseObject (req_http_-> responseBody ()).getBool ();
144
188
}
189
+
145
190
void FirebaseArduino::remove (const String& path) {
146
191
initRequest ();
147
- req_.get ()->sendRequest (host_, auth_, " DELETE" , path.c_str ());
148
- error_ = req_.get ()->error ();
192
+ String uri = makeFirebaseURI (path, auth_);
193
+ int err = req_http_->del (uri.c_str ());
194
+ if (err != 0 ) {
195
+ error_ = FirebaseError (err, " HTTP request failed" );
196
+ return ;
197
+ }
198
+ int statusCode = req_http_->responseStatusCode ();
199
+ if (statusCode != kStatusOK ) {
200
+ error_ = FirebaseError (statusCode, " PUT request failed" );
201
+ return ;
202
+ }
203
+ req_http_->responseBody (); // consume body;
149
204
}
150
205
151
206
void FirebaseArduino::stream (const String& path) {
152
207
initStream ();
153
- stream_.get ()->startStreaming (host_, auth_, path.c_str ());
154
- error_ = stream_.get ()->error ();
208
+ String uri = makeFirebaseURI (path, auth_);
209
+ stream_http_->beginRequest ();
210
+ stream_http_->get (uri.c_str ());
211
+ stream_http_->sendHeader (" Accept" , " text/event-stream" );
212
+ stream_http_->endRequest ();
213
+
214
+ int statusCode = stream_http_->responseStatusCode ();
215
+ if (statusCode != kStatusOK ) {
216
+ error_ = FirebaseError (statusCode, " STREAM request failed" );
217
+ return ;
218
+ }
219
+
220
+ if (statusCode == kStatusTemporaryRedirect ) {
221
+ while (stream_http_->headerAvailable ()) {
222
+ if (stream_http_->readHeaderName () == " Location" ) {
223
+ String location = stream_http_->readHeaderValue ();
224
+ int hostnameStart = location.indexOf (' :' )+2 ;
225
+ int hostnameEnd = location.indexOf (' /' , hostnameStart);
226
+ String hostname = location.substring (hostnameStart, hostnameEnd);
227
+ String path = location.substring (hostnameEnd);
228
+ client_.stop ();
229
+ stream_http_.reset (new HttpClient (client_, hostname, kFirebasePort ));
230
+ stream_http_->connectionKeepAlive ();
231
+ stream (path);
232
+ return ;
233
+ }
234
+ }
235
+ }
155
236
}
156
237
157
238
bool FirebaseArduino::available () {
158
239
if (stream_http_.get () == nullptr ) {
159
- return 0 ;
240
+ return false ;
160
241
}
161
- auto client = stream_http_.get ()->getStreamPtr ();
162
- return (client == nullptr ) ? false : client->available ();
242
+ return stream_http_->available ();
163
243
}
164
244
165
245
FirebaseObject FirebaseArduino::readEvent () {
166
246
if (stream_http_.get () == nullptr ) {
167
247
return FirebaseObject (" " );
168
248
}
169
- auto client = stream_http_.get ()->getStreamPtr ();
170
- if (client == nullptr ) {
171
- return FirebaseObject (" " );
172
- }
173
- String type = client->readStringUntil (' \n ' ).substring (7 );;
174
- String event = client->readStringUntil (' \n ' ).substring (6 );
175
- client->readStringUntil (' \n ' ); // consume separator
176
- FirebaseObject obj = FirebaseObject (event.c_str ());
249
+ String type = stream_http_->readStringUntil (' \n ' ).substring (7 );;
250
+ String event = stream_http_->readStringUntil (' \n ' ).substring (6 );
251
+ stream_http_->readStringUntil (' \n ' ); // consume separator
252
+ FirebaseObject obj = FirebaseObject (event);
177
253
obj.getJsonVariant ().asObject ()[" type" ] = type.c_str ();
178
254
return obj;
179
255
}
@@ -190,4 +266,11 @@ const String& FirebaseArduino::error() {
190
266
return error_.message ().c_str ();
191
267
}
192
268
193
- FirebaseArduino Firebase;
269
+
270
+ #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
271
+
272
+ #include < WiFiClientSecure.h>
273
+ WiFiClientSecure client;
274
+ FirebaseArduino Firebase (client);
275
+
276
+ #endif
0 commit comments