Skip to content
This repository was archived by the owner on Mar 17, 2025. It is now read-only.

Could I set key and listen a stream simultaneously? #193

Closed
hawkhsieh opened this issue Aug 10, 2016 · 24 comments
Closed

Could I set key and listen a stream simultaneously? #193

hawkhsieh opened this issue Aug 10, 2016 · 24 comments

Comments

@hawkhsieh
Copy link

I combine the FirebaseDemo and FirebaseStream to set a key and watch a key simultaneously.
The key is set successfully.
But it doesnt show "event:" on UART about stream function.
revesion is 854bb0c
source code is below:

//
// Copyright 2015 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

// FirebaseDemo_ESP8266 is a sample that demo the different functions
// of the FirebaseArduino API.

#include <ESP8266WiFi.h>
#include <FirebaseArduino.h>

// Set these to run example.
#define FIREBASE_HOST "api-project.firebaseio.com" 
#define FIREBASE_AUTH "nZPE6hBzwDXfCUYteuGIQ6dRJH2ac1Ldff7cP"
#define WIFI_SSID "NETGEAR29"
#define WIFI_PASSWORD "093548"

void setup() {
  Serial.begin(115200);

  // connect to wifi.
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("connecting");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println();
  Serial.print("connected: ");
  Serial.println(WiFi.localIP());

  Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
  Firebase.stream("/watch/device1");  

     if (Firebase.success()) {
          Serial.println("streaming ok");
     }
}

int n = 0;

void loop() {
  // set value
  Firebase.setFloat("number", 42.0);
  // handle error
  if (Firebase.failed()) {
      Serial.print("setting /number failed:42");
      Serial.println(Firebase.error());  
      delay(1000);
      return;
  }
  delay(3000);

  // update value
  Firebase.setFloat("number", 43.0);
  // handle error
  if (Firebase.failed()) {
      Serial.print("setting /number failed:43");
      Serial.println(Firebase.error());  
      return;
  }
  delay(3000);

  // get value 
  Serial.print("number: ");
  Serial.println(Firebase.getFloat("number"));
  delay(1000);

  // remove value
  Firebase.remove("number");
  delay(1000);

  // set string value
  Firebase.setString("message", "hello world");
  // handle error
  if (Firebase.failed()) {
      Serial.print("setting /message failed:");
      Serial.println(Firebase.error());  
      return;
  }
  delay(1000);

  // set bool value
  Firebase.setBool("truth", false);
  // handle error
  if (Firebase.failed()) {
      Serial.print("setting /truth failed:");
      Serial.println(Firebase.error());  
      return;
  }
  delay(1000);

  // append a new value to /logs
  String name = Firebase.pushInt("logs", n++);
  // handle error
  if (Firebase.failed()) {
      Serial.print("pushing /logs failed:");
      Serial.println(Firebase.error());  
      return;
  }
  Serial.print("pushed: /logs/");
  Serial.println(name);
  delay(1000);


    if (Firebase.available()) {
     FirebaseObject event = Firebase.readEvent();
     String eventType = event.getString("type");
     eventType.toLowerCase();

     Serial.print("event: ");
     Serial.println(eventType);
     if (eventType == "put") {
       Serial.print("data: ");
       Serial.println(event.getString("data"));
       String path = event.getString("path");
       String data = event.getString("data");
     }
  }  
}
@hawkhsieh hawkhsieh changed the title Could I combine set-key and stream simultaneously? Could I set key and listen a stream simultaneously? Aug 11, 2016
@Twoaster
Copy link

Hi hawkhsieh,
I had an issue like yours while using Firebase and the ESP8266 shield. To solve it, I had to declare 2 variables of the Firebase type like this:

Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH); FirebaseStream.begin(FIREBASE_HOST, FIREBASE_AUTH); FirebaseStream.stream(node);

Than you need to check the variable if (FirebaseStream.available()) { to see if there is any change on the database and use the variable Firebase.set("node","data"); to set and get data

Hope it can help!

@ghost
Copy link

ghost commented Aug 12, 2016

I am having similar issues. Specifically, a crash if I try to write anything to a FirebaseArduino that I am streaming from. Are you using the "Firebase" class (from Firebase.h/cpp) instead of FirebaseArduino? If so, could you share how you set this up? Thanks.

@tabvn
Copy link

tabvn commented Aug 29, 2016

The issue still existing i had is we could not do use both stream and get or push, or put .

put,post,get durring set streaming it will be get crash. (ESP8266)/ Seem Firebase had implements of esp8266httpclient but they still fixing this issue.

@proppy
Copy link
Contributor

proppy commented Sep 26, 2016

I was able to stream using two different FirebaseArduino instance, like described in #193 (comment)

FirebaseArduino FirebaseStream

It would be nice to have something simpler like described in #159

@RaemondBW
Copy link
Contributor

I think the issue this is referring to, as mentioned in a couple of other issues, is the inability to push/get while maintaining an open stream. Not having two simultaneous streams. For this case, I have tried having two FirebaseArduino instances and have yet to get it to work.

@proppy
Copy link
Contributor

proppy commented Sep 26, 2016

@RaemondBW we did manage to get it work with two FirebaseArduino instance in the past, see #48 (comment)

I'd be very interested to see if that snippet crash for people noticing that behavior, gather proper debugging and version information and try to reproduce the issue.

@RaemondBW
Copy link
Contributor

@proppy Here is an example sketch that exhibits the issue:

#include <FirebaseArduino.h>
#include <ESP8266WiFi.h>

FirebaseArduino firebaseRW;

//Placeholder values
#define FIREBASE_HOST "url.firebaseio.com"
#define FIREBASE_AUTH "auth token"
const String URL = "/value";


void setup() {
  Serial.begin(115200);
  Serial.println("Connecting to WiFi");
  WiFi.mode(WIFI_STA);
  WiFi.begin();
  while (WiFi.status() != WL_CONNECTED) {
    delay(10);
  }
  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("WiFi Connected");
    Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
    Firebase.stream(URL);
    firebaseRW.begin(FIREBASE_HOST, FIREBASE_AUTH);
  }
}

void loop() {
  if (Firebase.available()) {
    FirebaseObject event = Firebase.readEvent();
    String eventType = event.getString("type");
    if (eventType == "put") {
      Serial.print("value from stream: ");
      Serial.println(event.getInt("data"));
    }
  }

  delay(1000);
  firebaseRW.setInt(URL, 1);
  delay(100);
}

And the resulting error:

[HTTP-Client][begin] host: url.firebaseio.com port: 443 url: /value.json?auth=FIREBASE_AUTH httpsFingerprint: 7A 54 06 9B DC 7A 25 B3 86 8D 66 53 48 2C 0B 96 42 C7 B3 0A
[HTTP-Client] connected to url.firebaseio.com:443
[HTTP-Client][handleHeaderResponse] RX: 'HTTP/1.1 307 Temporary Redirect'
[HTTP-Client][handleHeaderResponse] RX: 'Content-Length: 0'
[HTTP-Client][handleHeaderResponse] RX: 'Content-Type: text/plain'
[HTTP-Client][handleHeaderResponse] RX: 'Location: https://s-usc1c-nss-109.firebaseio.com/value.json?auth=FIREBASE_AUTH&ns=url&sse=true'
[HTTP-Client][handleHeaderResponse] RX: 'Access-Control-Allow-Origin: *'
[HTTP-Client][handleHeaderResponse] RX: 'Strict-Transport-Security: max-age=31556926; includeSubDomains; preload'
[HTTP-Client][handleHeaderResponse] RX: ''
[HTTP-Client][handleHeaderResponse] code: 307
[HTTP-Client][end] tcp stop
[HTTP-Client][begin] url: https://s-usc1c-nss-109.firebaseio.com/value.json?auth=FIREBASE_AUTH&ns=url&sse=true
[HTTP-Client][begin] host: s-usc1c-nss-109.firebaseio.com port: 443 url: /value.json?auth=FIREBASE_AUTH&ns=url&sse=true
[HTTP-Client][begin] httpsFingerprint: 7A 54 06 9B DC 7A 25 B3 86 8D 66 53 48 2C 0B 96 42 C7 B3 0A
[HTTP-Client] connected to s-usc1c-nss-109.firebaseio.com:443
[HTTP-Client][handleHeaderResponse] RX: 'HTTP/1.1 200 OK'
[HTTP-Client][handleHeaderResponse] RX: 'Server: nginx'
[HTTP-Client][handleHeaderResponse] RX: 'Date: Mon, 26 Sep 2016 18:10:05 GMT'
[HTTP-Client][handleHeaderResponse] RX: 'Content-Type: text/event-stream'
[HTTP-Client][handleHeaderResponse] RX: 'Connection: close'
[HTTP-Client][handleHeaderResponse] RX: 'Cache-Control: no-cache'
[HTTP-Client][handleHeaderResponse] RX: 'Access-Control-Allow-Origin: *'
[HTTP-Client][handleHeaderResponse] RX: 'Strict-Transport-Security: max-age=31556926; includeSubDomains; preload'
[HTTP-Client][handleHeaderResponse] RX: ''
[HTTP-Client][handleHeaderResponse] code: 200

value from stream: 0

[HTTP-Client][begin] host: url.firebaseio.com port: 443 url: /value.json?auth=FIREBASE_AUTH httpsFingerprint: 7A 54 06 9B DC 7A 25 B3 86 8D 66 53 48 2C 0B 96 42 C7 B3 0A
please start sntp first !
State: sending Client Hello (1)
State:  receiving Server Hello (2)
State:   receiving Certificate (11)
Fatal exception 29(StoreProhibitedCause):
epc1=0x4000dfd9, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000

Exception (29):
epc1=0x4000dfd9 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

ctx: cont
sp: 3fff10f0 end: 3fff1c20 offset: 01a0

the stream starts successfully. When I try to write, the issue comes up.

@RaemondBW
Copy link
Contributor

I just tested the code at Comment #48 and it results in the same crash.

@proppy
Copy link
Contributor

proppy commented Sep 30, 2016

@RaemondBW can you confirm which version of the arduino core you're using?

@RaemondBW
Copy link
Contributor

@proppy I tested with arduino 1.6.12 and the latest release of FirebaseArduino

@proppy
Copy link
Contributor

proppy commented Sep 30, 2016

@RaemondBW which version of the Arduino ESP core https://github.com/esp8266/Arduino?

@RaemondBW
Copy link
Contributor

@proppy sorry, ESP Core version 2.3.0

@proppy
Copy link
Contributor

proppy commented Oct 4, 2016

merging with #48

@proppy proppy closed this as completed Oct 4, 2016
@am-canes
Copy link

I am trying to solve the problem using two different FirebaseArduino instance, like described in the comments. It works for some time, but after some minutes the stream keep working but the set doesn't work anymore.
Anyone has a solution?

@MrSuhov
Copy link

MrSuhov commented Jul 1, 2018

@am-canes, I am having exactly the same issue.
I have also noticed a different behavior for using mobile-shared WiFi and a regular WiFi.

In the evening I will try to use three separate firebase clients: one for stream, one for reading and one for writing.

@am-canes
Copy link

am-canes commented Jul 2, 2018

@MrSuhov Please, let me know the results of your tests.

@tabvn
Copy link

tabvn commented Jul 2, 2018

2 years ago my first comment researching use firebase with arduino. i think now this library is ok ?
if no Amazon IOT is next solution :) support all environments with strong library.

@MrSuhov
Copy link

MrSuhov commented Jul 2, 2018

Unfortunately I am alwas running out of heap (Exception 29) using three clients - dead end.
Anyway, with two clients (Firebase and FirebaseStream) everything works fine until here:

10:20:56.260 -> [HTTP-Client] connect. already connected, try reuse!
10:20:56.306 -> Alert: close notify
10:20:56.306 -> [HTTP-Client][returnError] error(-2): send header failed
10:20:56.306 -> [HTTP-Client][returnError] error(-4): not connected

After these errors nither .getString nor .setInt dont work with Firebase client.
Every Firebase.getString attempt results in empty string "" even when server response is ok:

10:32:37.677 -> [HTTP-Client] connected to idhomepulse.firebaseio.com:443
10:32:37.724 -> [HTTP-Client] sending request header
10:32:37.724 -> -----
10:32:37.724 -> GET /ios@rsolarcom/test/infrastructure/2/name.json?auth= HTTP/1.1
10:32:37.724 -> Host: .firebaseio.com
10:32:37.724 -> User-Agent: ESP8266HTTPClient
10:32:37.724 -> Connection: keep-alive
10:32:37.724 -> Accept-Encoding: identity;q=1,chunked;q=0.1,*;q=0
10:32:37.724 ->
10:32:37.724 -> -----
10:32:37.911 -> [HTTP-Client][handleHeaderResponse] RX: 'HTTP/1.1 200 OK'
10:32:37.911 -> [HTTP-Client][handleHeaderResponse] RX: 'Server: nginx'
10:32:37.911 -> [HTTP-Client][handleHeaderResponse] RX: 'Date: Mon, 02 Jul 2018 07:32:37 GMT'
10:32:37.911 -> [HTTP-Client][handleHeaderResponse] RX: 'Content-Type: application/json; charset=utf-8'
10:32:37.911 -> [HTTP-Client][handleHeaderResponse] RX: 'Content-Length: 11'
10:32:37.911 -> [HTTP-Client][handleHeaderResponse] RX: 'Connection: keep-alive'
10:32:37.958 -> [HTTP-Client][handleHeaderResponse] RX: 'Access-Control-Allow-Origin: *'
10:32:37.958 -> [HTTP-Client][handleHeaderResponse] RX: 'Cache-Control: no-cache'
10:32:37.958 -> [HTTP-Client][handleHeaderResponse] RX: 'Strict-Transport-Security: max-age=31556926; includeSubDomains; preload'
10:32:37.958 -> [HTTP-Client][handleHeaderResponse] RX: ''
10:32:37.958 -> [HTTP-Client][handleHeaderResponse] code: 200
10:32:37.958 -> [HTTP-Client][handleHeaderResponse] size: 11
10:32:37.976 -> [HTTP-Client][writeToStreamDataBlock] connection closed or file end (written: 11).
10:32:37.977 -> [HTTP-Client][end] tcp keep open for reuse

Stream client (FirebaseStream) keep working as expected all that time.
I will try to reproduce this on an example sketch to save space and will update this message with a sketch code.

UPD. Sketch that reproduces the issue:
#include <ESP8266WiFi.h>
#include <FirebaseArduino.h>
#include <HomePulse.h>
#include <ArduinoJson.h>

FirebaseArduino FirebaseStream;

void setup() {
Serial.begin(115200);
ConnectToPrefNetwork();

Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
FirebaseStream.begin(FIREBASE_HOST, FIREBASE_AUTH);
FirebaseStream.stream(String(fuser) + String(stand) + "/infrastructure");
}

void loop() {
if (FirebaseStream.failed()) {
Serial.println("streaming error");
Serial.println(FirebaseStream.error());
}

if (FirebaseStream.available()) {
FirebaseObject event = FirebaseStream.readEvent();
String eventType = event.getString("type");
eventType.toLowerCase();
String path = event.getString("path");
int data = event.getInt("data");
String lastindex = path.substring(0, path.lastIndexOf("/"));
String roomid = path.substring(lastindex.lastIndexOf("/") + 1, path.lastIndexOf("/"));
Serial.println("path = " + String(fuser) + String(stand) + path + "/" + roomid +", value = " + String(data));
if (path.endsWith("/on")) {
String infraname = Firebase.getString(String(fuser) + String(stand) + "/infrastructure/" + roomid + "/name");
Serial.println("Infraname = " + infraname);
if (infraname == "frontdoor") {
Firebase.setInt(String(fuser) + String(stand) + "/infrastructure/" + roomid + "/state", data);
}
}
}
}

void ConnectToPrefNetwork() {
int retry = 0;
WiFi.disconnect();
WiFi.mode(WIFI_OFF);
int numSsid = WiFi.scanNetworks();
if (numSsid == -1) {
Serial.println(F("Couldn't find known wifi"));
return;
}
for (int thisNet = 0; thisNet < numSsid; thisNet++) {
for (int ni = 0; ni < NumKnownNetworks; ni++) {
if ((WiFi.SSID(thisNet) == ssid[ni]) and ((WiFi.status() != WL_CONNECTED)))
{
byte pnet = ni;
WiFi.mode(WIFI_STA);
Serial.println("wifi begin: " + String (ssid[ni]));
WiFi.begin(ssid[ni], pass[ni]);
retry = millis();
Serial.print(F("Connecting"));
while (WiFi.status() != WL_CONNECTED)
{
delay(100);
Serial.print(".");
yield();
if ((millis() - retry) > 10000) {
Serial.println(F("could not connect in 10 sec, aborting..."));
break;
}
}
}
if (WiFi.status() == WL_CONNECTED) break;
}
if (WiFi.status() == WL_CONNECTED) break;
}
}

Compile options:
image
Latest Arduino esp8266 core is used.

@kotl
Copy link
Collaborator

kotl commented Jul 2, 2018

Since this change:
#330

What you are asking for is supported. Both streaming and setting keys. You don't need two instances, just use one. Make sure to use 2.4.1 Arduino core:
https://github.com/esp8266/Arduino/tree/2.4.1

@kotl
Copy link
Collaborator

kotl commented Jul 2, 2018

Also note: using 2.4.1 Arduino core is absolutely essential because simultaneous HTTPS connections did not work properly before resulting in random reboots and random crashes due to bugs in HTTPS library not able to support more than one https context at the same time.
Change #330 actually creates (on demand) two https connections if you use both streaming and setting at the same time, therefore you do not need to use two FirebaseArduino instances anymore.

@MrSuhov
Copy link

MrSuhov commented Jul 3, 2018

@kotl thanks a lot! Yes, the core is 2.4.1.
10 hours so far under one instance - the flight is OK.

@am-canes
Copy link

am-canes commented Jul 4, 2018

@kotl I was already using core 2.4.1. Now I am using just one FirebaseArduino instance but the problem is still happening. I am using set and stream in to different places. I set the firebase value when temperature sensor value read by AD converter changes. And I have the stream in the loop waiting for events too.
It works for a while, but after a few minutes only the stream keeps running.

@am-canes
Copy link

am-canes commented Jul 5, 2018

The error that occurs when firebase fails is:

[HTTP-Client] connect. already connected, try reuse!
Alert: close notify
[HTTP-Client][returnError] error(-2): send header failed
[HTTP-Client][returnError] error(-4): not connected

@MrSuhov
Copy link

MrSuhov commented Jul 5, 2018

Give it a second try. The connection will be re-established. At least in my case it works.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

8 participants