Skip to content

Merge my fork up to head. #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 42 commits into from
Feb 23, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
0a613cd
Refactor Firebase module, split into more focues subclasses, change r…
ed7coyne Jan 12, 2016
d805dc6
removed FirebaseResultWithMessage consolidated into one for simplicity
ed7coyne Jan 12, 2016
217d58f
Added comments for clarify
ed7coyne Jan 12, 2016
28997ff
Add Gitter badge
gitter-badger Jan 13, 2016
c0afb45
Merge pull request #44 from gitter-badger/gitter-badge
proppy Jan 13, 2016
b2438cf
removed old reference to FirebaseResultWithMessage
ed7coyne Jan 13, 2016
d5dd303
Refactor out FirebaseCall
ed7coyne Jan 14, 2016
23fbbed
possibly fix streaming example
ed7coyne Jan 14, 2016
2bf3a4f
Move helper classes below Firebase in Firebase.h
ed7coyne Jan 14, 2016
2df5bd6
Added error message back to streaming imp
ed7coyne Jan 14, 2016
8579526
Firebase Arduino Shield.
aliafshar Jan 14, 2016
4acc510
Merge branch 'master' of https://github.com/googlesamples/firebase-ar…
aliafshar Jan 19, 2016
18deb49
Merge pull request #40 from ed7coyne/master
proppy Jan 20, 2016
7561f36
firebase: add set
proppy Jan 20, 2016
4cae3f8
Merge pull request #47 from proppy/set
ed7coyne Jan 20, 2016
077e060
Add call ids
ed7coyne Jan 26, 2016
6f65250
Revert "Add call ids"
ed7coyne Jan 27, 2016
33f81ef
Added independant opaque return types for all calls.
ed7coyne Jan 28, 2016
2ac7ab3
Remove unused method declaration.
ed7coyne Jan 28, 2016
357a1d0
firebase: refactor the refactoring
proppy Jan 28, 2016
c65fef7
Merge pull request #2 from proppy/refactor-12
ed7coyne Jan 28, 2016
b286b19
firebase: fix stream example
proppy Jan 29, 2016
34357a9
Merge pull request #3 from proppy/refactor
ed7coyne Jan 29, 2016
f38602f
merge
proppy Jan 29, 2016
e8ac1e9
examples/stream: fix error handling
proppy Jan 29, 2016
caa70e9
Merge pull request #4 from proppy/refactor-merge-3
ed7coyne Jan 29, 2016
96f7d8e
Merge pull request #42 from ed7coyne/refactor
proppy Jan 29, 2016
68fa4e0
examples/push: fix constructor syntax
proppy Jan 30, 2016
64a5de8
Merge pull request #50 from googlesamples/proppy-patch-1
proppy Jan 30, 2016
42aa5bf
stream: use ArduinoJson
proppy Feb 2, 2016
52e7a7f
firebase: restore set method
proppy Feb 2, 2016
65ec1bf
firebase: better docstrings
proppy Feb 2, 2016
74ee904
Merge pull request #53 from proppy/missing-set
ed7coyne Feb 2, 2016
fdf18aa
Merge pull request #51 from proppy/new-json
ed7coyne Feb 2, 2016
409c806
Add support for stable branch of HTTP client library, fixes small whi…
gguuss Feb 3, 2016
0f6ce71
Feedback from review
gguuss Feb 4, 2016
d3a4c1b
Adds link to stable installer via boards manager
gguuss Feb 5, 2016
7d38e14
README: update arduino board definition link
proppy Feb 8, 2016
b8ae21c
Firebase: update arduino core define
proppy Feb 8, 2016
2ef045b
Merge pull request #1 from proppy/patch-1
gguuss Feb 9, 2016
f3dcace
Merge pull request #2 from proppy/patch-2
gguuss Feb 9, 2016
424e1bf
Merge pull request #63 from gguuss/compat
proppy Feb 9, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
200 changes: 130 additions & 70 deletions Firebase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,109 +15,169 @@
//
#include "Firebase.h"

const char* firebaseFingerprint = "7A 54 06 9B DC 7A 25 B3 86 8D 66 53 48 2C 0B 96 42 C7 B3 0A";
const uint16_t firebasePort = 443;
// Detect whether stable version of HTTP library is installed instead of
// master branch and patch in missing status and methods.
#ifndef HTTP_CODE_TEMPORARY_REDIRECT
#define HTTP_CODE_TEMPORARY_REDIRECT 307
#define USE_ESP_ARDUINO_CORE_2_0_0
#endif

Firebase::Firebase(const String& host) : _host(host) {
_http.setReuse(true);
namespace {
const char* kFirebaseFingerprint = "7A 54 06 9B DC 7A 25 B3 86 8D 66 53 48 2C 0B 96 42 C7 B3 0A";
const uint16_t kFirebasePort = 443;

String makeFirebaseURL(const String& path, const String& auth) {
String url;
if (path[0] != '/') {
url = "/";
}
url += path + ".json";
if (auth.length() > 0) {
url += "?auth=" + auth;
}
return url;
}

} // namespace

Firebase::Firebase(const String& host) : host_(host) {
http_.setReuse(true);
}

Firebase& Firebase::auth(const String& auth) {
_auth = auth;
auth_ = auth;
return *this;
}

String Firebase::get(const String& path) {
sendRequest("GET", path);
return readBody();
FirebaseGet Firebase::get(const String& path) {
return FirebaseGet(host_, auth_, path, &http_);
}

FirebaseSet Firebase::set(const String& path, const String& value) {
return FirebaseSet(host_, auth_, path, value, &http_);
}

String Firebase::push(const String& path, const String& value) {
sendRequest("POST", path, value);
return readBody();
FirebasePush Firebase::push(const String& path, const String& value) {
return FirebasePush(host_, auth_, path, value, &http_);
}

void Firebase::remove(const String& path) {
sendRequest("DELETE", path);
FirebaseRemove Firebase::remove(const String& path) {
return FirebaseRemove(host_, auth_, path, &http_);
}

Firebase& Firebase::stream(const String& path) {
_error.reset();
String url = makeURL(path);
const char* headers[] = {"Location"};
_http.setReuse(true);
_http.begin(_host.c_str(), firebasePort, url.c_str(), true, firebaseFingerprint);
_http.collectHeaders(headers, 1);
_http.addHeader("Accept", "text/event-stream");
int statusCode = _http.sendRequest("GET", (uint8_t*)NULL, 0);
String location;
// TODO(proppy): Add a max redirect check
while (statusCode == 307) {
location = _http.header("Location");
_http.setReuse(false);
_http.end();
_http.setReuse(true);
_http.begin(location, firebaseFingerprint);
statusCode = _http.sendRequest("GET", (uint8_t*)NULL, 0);
FirebaseStream Firebase::stream(const String& path) {
// TODO: create new client dedicated to stream.
return FirebaseStream(host_, auth_, path, &http_);
}

// FirebaseCall
FirebaseCall::FirebaseCall(const String& host, const String& auth,
const char* method, const String& path,
const String& data, HTTPClient* http) : http_(http) {
String url = makeFirebaseURL(path, auth);
http_->setReuse(true);
http_->begin(host, kFirebasePort, url, true, kFirebaseFingerprint);

bool followRedirect = false;
if (method == "STREAM") {
method = "GET";
http_->addHeader("Accept", "text/event-stream");
followRedirect = true;
}
if (statusCode != 200) {
_error.set(statusCode,
"stream " + location + ": "
+ HTTPClient::errorToString(statusCode));

if (followRedirect) {
const char* headers[] = {"Location"};
http_->collectHeaders(headers, 1);
}
return *this;
}

String Firebase::makeURL(const String& path) {
String url;
if (path[0] != '/') {
url = "/";
int status = http_->sendRequest(method, (uint8_t*)data.c_str(), data.length());

// TODO: Add a max redirect check
if (followRedirect) {
while (status == HTTP_CODE_TEMPORARY_REDIRECT) {
String location = http_->header("Location");
http_->setReuse(false);
http_->end();
http_->setReuse(true);
http_->begin(location, kFirebaseFingerprint);
status = http_->sendRequest("GET", (uint8_t*)NULL, 0);
}
}
url += path + ".json";
if (_auth.length() > 0) {
url += "?auth=" + _auth;

if (status != 200) {
#ifdef USE_ESP_ARDUINO_CORE_2_0_0
error_ = FirebaseError(status, String(method) + " " + url + ": " + status);
#else
error_ = FirebaseError(status, String(method) + " " + url + ": " + HTTPClient::errorToString(status));
#endif
}

// if not streaming.
if (!followRedirect) {
response_ = http_->getString();
}
return url;
}

void Firebase::sendRequest(const char* method, const String& path, const String& value) {
String url = makeURL(path);
_http.begin(_host.c_str(), firebasePort, url.c_str(), true, firebaseFingerprint);
int statusCode = _http.sendRequest(method, (uint8_t*)value.c_str(), value.length());
_error.reset();
if (statusCode < 0) {
_error.set(statusCode,
String(method) + " " + url + ": "
+ HTTPClient::errorToString(statusCode));
}
// FirebaseGet
FirebaseGet::FirebaseGet(const String& host, const String& auth,
const String& path,
HTTPClient* http)
: FirebaseCall(host, auth, "GET", path, "", http) {
if (!error()) {
// TODO: parse json
json_ = response();
}
}

String Firebase::readBody() {
if (_error.code() != 0) {
return "";
// FirebaseSet
FirebaseSet::FirebaseSet(const String& host, const String& auth,
const String& path, const String& value,
HTTPClient* http)
: FirebaseCall(host, auth, "PUT", path, value, http) {
if (!error()) {
// TODO: parse json
json_ = response();
}
// no _http.end() because of connection reuse.
return _http.getString();
}
// FirebasePush
FirebasePush::FirebasePush(const String& host, const String& auth,
const String& path, const String& value,
HTTPClient* http)
: FirebaseCall(host, auth, "POST", path, value, http) {
if (!error()) {
// TODO: parse name
name_ = response();
}
}

// FirebasePush
FirebaseRemove::FirebaseRemove(const String& host, const String& auth,
const String& path,
HTTPClient* http)
: FirebaseCall(host, auth, "DELETE", path, "", http) {
}

bool Firebase::connected() {
return _http.connected();
// FirebaseStream
FirebaseStream::FirebaseStream(const String& host, const String& auth,
const String& path,
HTTPClient* http)
: FirebaseCall(host, auth, "STREAM", path, "", http) {
}

bool Firebase::available() {
return _http.getStreamPtr()->available();
bool FirebaseStream::available() {
return http_->getStreamPtr()->available();
}

Firebase::Event Firebase::read(String& event) {
auto client = _http.getStreamPtr();
Event type;;
FirebaseStream::Event FirebaseStream::read(String& event) {
auto client = http_->getStreamPtr();
Event type;
String typeStr = client->readStringUntil('\n').substring(7);
if (typeStr == "put") {
type = Firebase::Event::PUT;
type = Event::PUT;
} else if (typeStr == "patch") {
type = Firebase::Event::PATCH;
type = Event::PATCH;
} else {
type = Firebase::Event::UNKNOWN;
type = Event::UNKNOWN;
}
event = client->readStringUntil('\n').substring(6);
client->readStringUntil('\n'); // consume separator
Expand Down
Loading