GithubHelp home page GithubHelp logo

firego's Introduction

Firego

Deprecated in favor of firebase/firebase-admin-go.


Build Status Coverage Status

A Firebase client written in Go

Installation

go get -u gopkg.in/zabawaba99/firego.v1

Usage

Import firego

import "gopkg.in/zabawaba99/firego.v1"

Create a new firego reference

f := firego.New("https://my-firebase-app.firebaseIO.com", nil)

with existing http client

f := firego.New("https://my-firebase-app.firebaseIO.com", client)

Request Timeouts

By default, the Firebase reference will timeout after 30 seconds of trying to reach a Firebase server. You can configure this value by setting the global timeout duration

firego.TimeoutDuration = time.Minute

Authentication

You can authenticate with your service_account.json file by using the golang.org/x/oauth2 package (thanks @m00sey for the snippet)

d, err := ioutil.ReadFile("our_service_account.json")
if err != nil {
    return nil, err
}

conf, err := google.JWTConfigFromJSON(d, "https://www.googleapis.com/auth/userinfo.email",
    "https://www.googleapis.com/auth/firebase.database")
if err != nil {
    return nil, err
}

fb := firego.New("https://you.firebaseio.com", conf.Client(oauth2.NoContext))
// use the authenticated fb instance

Legacy Tokens

f.Auth("some-token-that-was-created-for-me")
f.Unauth()

Visit Fireauth if you'd like to generate your own auth tokens

Get Value

var v map[string]interface{}
if err := f.Value(&v); err != nil {
  log.Fatal(err)
}
fmt.Printf("%s\n", v)

Querying

Take a look at Firebase's query parameters for more information on what each function does.

var v map[string]interface{}
if err := f.StartAt("a").EndAt("c").LimitToFirst(8).OrderBy("field").Value(&v); err != nil {
	log.Fatal(err)
}
fmt.Printf("%s\n", v)

Set Value

v := map[string]string{"foo":"bar"}
if err := f.Set(v); err != nil {
  log.Fatal(err)
}

Push Value

v := "bar"
pushedFirego, err := f.Push(v)
if err != nil {
	log.Fatal(err)
}

var bar string
if err := pushedFirego.Value(&bar); err != nil {
	log.Fatal(err)
}

// prints "https://my-firebase-app.firebaseIO.com/-JgvLHXszP4xS0AUN-nI: bar"
fmt.Printf("%s: %s\n", pushedFirego, bar)

Update Child

v := map[string]string{"foo":"bar"}
if err := f.Update(v); err != nil {
  log.Fatal(err)
}

Remove Value

if err := f.Remove(); err != nil {
  log.Fatal(err)
}

Watch a Node

notifications := make(chan firego.Event)
if err := f.Watch(notifications); err != nil {
	log.Fatal(err)
}

defer f.StopWatching()
for event := range notifications {
	fmt.Printf("Event %#v\n", event)
}
fmt.Printf("Notifications have stopped")

Change reference

You can use a reference to save or read data from a specified reference

userID := "bar"
usersRef,err := f.Ref("users/"+userID)
if err != nil {
  log.Fatal(err)
}
v := map[string]string{"id":userID}
if err := usersRef.Set(v); err != nil {
  log.Fatal(err)
}

Check the GoDocs or Firebase Documentation for more details

Running Tests

In order to run the tests you need to go get -t ./... first to go-get the test dependencies.

Issues Management

Feel free to open an issue if you come across any bugs or if you'd like to request a new feature.

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b new-feature)
  3. Commit your changes (git commit -am 'Some cool reflection')
  4. Push to the branch (git push origin new-feature)
  5. Create new Pull Request

firego's People

Contributors

acomagu avatar alvivi avatar apita1973 avatar crystalin avatar fabienfoerster avatar gabriel avatar hostirosti avatar ianlewis avatar keuller avatar mrgossett avatar rakyll avatar smartrevolution avatar theprojectabot avatar tonkpils avatar tqwewe avatar vzsg avatar zabawaba99 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

firego's Issues

Numeric string escapes to int in query

Because type of *Firebase.EqualTo (and other querying functions) argument is string, request asking for value "1234" is the same as the request asking for 1234 - they are both numeric. However firebase treats them differently, and so it's impossible to make query for numeric string (for example "1234").

Filtering using OrderBy does not working

Hi guys,

I'm trying to filter some data using the strategy "by a specified child key" as Firebase documentation shows. But its not working for me. Here is my code:

    courses := ref.Child("courses").OrderBy("author").StartAt(author)
    fmt.Println(courses.String())
    result := make(map[string]Course, 0)
    courses.Value(&result)
    return result

When I try to view the URL which Firego tries to connect (through .String() method) I just see that: https://[domain].firebaseio.com/courses instead of https://[domain].firebaseio.com/courses.json?orderBy="author" as shown by Firebase documentation.

Anyone can help me ?

Watch(Event) should be be able to unmarshal to user-defined struct

Hi,

I have a patch that makes it possible to Unmarshal the Data-field of an Event into a user-defined struct.

The problem with the current implementation is, that the Data-Field always returns map[string]interface{} and it can happen, that i.e. numbers are unmarshaled in a way you would not expect. For example unix timestamps are returned as float64. Using Decoder.UseNumber is not enough to fix the problem.

Are you interested?

cheers
'(stefan)

ChildAdded doesn't work with a big amount of children

if a node has 700-1000 children or more there are no calls to add child handler function. However, if a number of children are 100-300 handler is called a number of children times.
Children are light-weight objects with 5-6 simple type fields. In a rare number of times, I've got calls but not as many as the number of children.
I think it isn't a problem of firebase because with nodejs sdk it works fine.

EqualTo ? request

Was wondering if there was a reason EqualTo wasn't included in query.go?
I can implement in my fork and make a PR

how do I authenticate with firebase v3?

In the old firebase v2, I was able to generate a token, and auth with that. Is it possible to use the service json file that Google gives you with this library?

Race Condition During Request Timeout

The current timeout logic for commit 6a3bac8 produces race conditions since http.Transport spawns a go routine when dialing a new connection.

Few possible solutions:

  • Wrap http.Transport in a custom struct and lock ResponseHeaderTimeout
  • Drop support for ResponseHeaderTimeout
  • Dive deeper into http.Transport and see what the alternatives are
==================
WARNING: DATA RACE
Write by goroutine 100:
  github.com/CloudCom/firego.func·001()
      /home/travis/gopath/src/myproject/package/Godeps/_workspace/src/github.com/CloudCom/firego/firebase.go:66 +0x165
  net/http.(*Transport).dial()
      /usr/local/go/src/net/http/transport.go:479 +0xc7
  net/http.(*Transport).dialConn()
      /usr/local/go/src/net/http/transport.go:564 +0x1d25
  net/http.func·019()
      /usr/local/go/src/net/http/transport.go:520 +0x8d

Previous read by goroutine 99:
  net/http.(*persistConn).roundTrip()
      /usr/local/go/src/net/http/transport.go:1089 +0x86d
  net/http.(*Transport).RoundTrip()
      /usr/local/go/src/net/http/transport.go:235 +0x6b7
  net/http.send()
      /usr/local/go/src/net/http/client.go:219 +0x6f2
  net/http.(*Client).send()
      /usr/local/go/src/net/http/client.go:142 +0x200
  net/http.(*Client).Do()
      /usr/local/go/src/net/http/client.go:179 +0x28b
  github.com/CloudCom/firego.(*Firebase).doRequest()
      /home/travis/gopath/src/myproject/package/Godeps/_workspace/src/github.com/CloudCom/firego/firebase.go:137 +0x169
  github.com/CloudCom/firego.(*Firebase).Remove()
      /home/travis/gopath/src/github.com/CitrixConcierge/firebirds/Godeps/_workspace/src/github.com/CloudCom/firego/remove.go:5 +0x79

Goroutine 100 (running) created at:
  net/http.(*Transport).getConn()
      /usr/local/go/src/net/http/transport.go:522 +0x470
  net/http.(*Transport).RoundTrip()
      /usr/local/go/src/net/http/transport.go:228 +0x62e
  net/http.send()
      /usr/local/go/src/net/http/client.go:219 +0x6f2
  net/http.(*Client).send()
      /usr/local/go/src/net/http/client.go:142 +0x200
  net/http.(*Client).Do()
      /usr/local/go/src/net/http/client.go:179 +0x28b
  github.com/CloudCom/firego.(*Firebase).doRequest()
      /home/travis/gopath/src/myproject/package/Godeps/_workspace/src/github.com/CloudCom/firego/firebase.go:137 +0x169
  github.com/CloudCom/firego.(*Firebase).Remove()
      /home/travis/gopath/src/myproject/package/Godeps/_workspace/src/github.com/CloudCom/firego/remove.go:5 +0x79

Goroutine 99 (running) created at:
  myproject/package.(*Struct).someFunc()
      /home/travis/gopath/src/myproject/package/some_func.go:82 +0x895
  myproject/package.(*Struct).someFunction()
      /home/travis/gopath/src/myproject/package/some_func2.go:59 +0x5ca
  myproject/package.(*Struct).someFunction2()
      /home/travis/gopath/src/myproject/package/some_func2.go:25 +0x666
==================

Maps with sequential keys rendered as array

If my value I want to store in Firebase is like below:

{
  "3" : {
    "338" : {...},
    "339" : {...},
    "340" : {...}
  },
  "5" : {
    "385" : {...},
    "386" : {...}
  }
}

Everything turns out fine. This is equal to a map[int]map[int]value, and it gets and sets the values just fine.

The moment I have sequential numbers:

{
  "3" : {
    "338" : {...},
    "339" : {...},
    "340" : {...}
  },
  "4": {}
  "5" : {
    "385" : {...},
    "386" : {...}
  }
}

Firebase stores it as a sequential array with the keys being the index values, hence the first three nulls (index 0-2, before 3):

[ null, null, null, {
  "338" : {...},
  "339" : {...},
  "340" : {...},
  "341" : {...}
}, {...
  "361" : {...},
  "362" : {...}
}, {
  "385" : {...},
  "386" : {...}
} ]

Support for different params per Reference

At the moment, the params are shared for all the references to the Firebase object.
Ex:
refA = fb.Child("/first_node")
refB = fb.Child("/another_node")

refA.Shallow(true) will also set shallow param to refB

OrderByValue

I have a large list of id:token data. I need to get id that corresponds to particular token. .OrderBy("$value").EqualTo(token).Value(&value) gives me nothing

Change Firebase reference without re-authing?

I don't think this feature exists as of yet, but it would be handy if there was a simple function to change the location of the firebase reference so I do not need to re-authenticate each time I change my reference.

Add Child Event Listeners

Some snippets of what it looks like on different Firebase SDK

Javascript

// Get a reference to our posts
var ref = new Firebase("https://docs-examples.firebaseio.com/web/saving-data/fireblog/posts");

// Retrieve new posts as they are added to our database
ref.on("child_added", function(snapshot, prevChildKey) {
  var newPost = snapshot.val();
  console.log("Author: " + newPost.author);
  console.log("Title: " + newPost.title);
  console.log("Previous Post ID: " + prevChildKey);
});

ios

// Get a reference to our posts
Firebase *ref = [[Firebase alloc] initWithUrl: @"https://docs-examples.firebaseio.com/web/saving-data/fireblog/posts"];

// Retrieve new posts as they are added to the database
[ref observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot *snapshot) {
  NSLog(@"%@", snapshot.value[@"author"]);
  NSLog(@"%@", snapshot.value[@"title"]);
}];

android

// Get a reference to our posts
Firebase ref = new Firebase("https://docs-examples.firebaseio.com/web/saving-data/fireblog/posts");

ref.addChildEventListener(new ChildEventListener() {
    // Retrieve new posts as they are added to the database
    @Override
    public void onChildAdded(DataSnapshot snapshot, String previousChildKey) {
        BlogPost newPost = snapshot.getValue(BlogPost.class);
        System.out.println("Author: " + newPost.getAuthor());
        System.out.println("Title: " + newPost.getTitle());
    }

    //... ChildEventListener also defines onChildChanged, onChildRemoved,
    //    onChildMoved and onCanceled, covered in later sections.
});

The go interface will use callbacks similarly to how the other firebase sdks.

Methods to be added:

  • ChildAdded
  • ChildChanged
  • ChildRemoved
  • ChildMoved

Race condition in StopWatching()

It looks like it's not safe to have multiple callers to the StopWatching() method. Two back-to-back callers could both see true from isWatching() and then the second call would block forever on the stopWatching channel.

It would be fine if that was a rule: "don't call StopWatching() multiple times", but the go-routine started by Watch() actually calls StopWatching(), so the only way to avoid the race is to never call StopWatching() asynchronously?

runtime/cgo: pthread_create failed: Resource temporarily unavailable

i keep running into this error in production. it doesn't happen right away. it only happens after running for about 10 hours. i've been trying to debug it for a week without any success. does anyone have this issue before? any advice is much appreciated.

note: i'm running it on 32 bit arm board (raspberry pi or nvidia tegra k1). i'm running the same code on my laptop / desktop and haven't seen any similar crash yet, but it may be just a matter of time that it will crash.

thanks.

runtime/cgo: pthread_create failed: Resource temporarily unavailable
SIGABRT: abort
PC=0xb6dac926 m=264
goroutine 0 [idle]:
goroutine 0 [idle]:
goroutine 8 [running]:
runtime.systemstack_switch()
/usr/local/go/src/runtime/asm_arm.s:192 +0x4 fp=0x10925764 sp=0x10925760
runtime.goready(0x109628f0, 0x0)
/usr/local/go/src/runtime/proc.go:274 +0x34 fp=0x10925778 sp=0x10925764
runtime.goroutineReady(0x408f08, 0x109628f0, 0x0)
/usr/local/go/src/runtime/time.go:82 +0x34 fp=0x10925788 sp=0x10925778
runtime.timerproc()
/usr/local/go/src/runtime/time.go:196 +0x2ec fp=0x109257dc sp=0x10925788
runtime.goexit()
/usr/local/go/src/runtime/asm_arm.s:990 +0x4 fp=0x109257dc sp=0x109257dc
created by runtime.addtimerLocked
/usr/local/go/src/runtime/time.go:116 +0x1c4

goroutine 17 [syscall, 122 minutes, locked to thread]:
runtime.goexit()
/usr/local/go/src/runtime/asm_arm.s:990 +0x4

goroutine 49 [IO wait]:
net.runtime_pollWait(0xb63d1148, 0x72, 0x10abc000)
/usr/local/go/src/runtime/netpoll.go:160 +0x60
net.(_pollDesc).Wait(0x10960638, 0x72, 0x0, 0x0)
/usr/local/go/src/net/fd_poll_runtime.go:73 +0x34
net.(_pollDesc).WaitRead(0x10960638, 0x0, 0x0)
/usr/local/go/src/net/fd_poll_runtime.go:78 +0x30
net.(_netFD).Read(0x10960600, 0x10abc000, 0x400, 0x400, 0x0, 0xb5390018, 0x1096c000)
/usr/local/go/src/net/fd_unix.go:250 +0x1c4
net.(_conn).Read(0x1094e078, 0x10abc000, 0x400, 0x400, 0x0, 0x0, 0x0)
/usr/local/go/src/net/net.go:172 +0xc8
crypto/tls.(_block).readFromUntil(0x10d965a0, 0xb5398bc8, 0x1094e078, 0x5, 0x0, 0x0)
/usr/local/go/src/crypto/tls/conn.go:460 +0xc8
crypto/tls.(_Conn).readRecord(0x109741c0, 0x5c0917, 0x0, 0x0)
/usr/local/go/src/crypto/tls/conn.go:562 +0x240
crypto/tls.(_Conn).Read(0x109741c0, 0x10bd2000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
/usr/local/go/src/crypto/tls/conn.go:939 +0x13c
net/http.noteEOFReader.Read(0xb63dba78, 0x109741c0, 0x10a066c4, 0x10bd2000, 0x1000, 0x1000, 0x3fe20, 0x0, 0x0)
/usr/local/go/src/net/http/transport.go:1690 +0x5c
net/http.(_noteEOFReader).Read(0x10d94290, 0x10bd2000, 0x1000, 0x1000, 0x1, 0x0, 0x0)
:284 +0xd0
bufio.(_Reader).Read(0x10d15d40, 0x10bd2000, 0x1000, 0x1000, 0x10bd8be4, 0x0, 0x0)
/usr/local/go/src/bufio/bufio.go:197 +0x10c
net/http.(_body).readLocked(0x10bcf590, 0x10bd2000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
/usr/local/go/src/net/http/transfer.go:651 +0x94
net/http.(_body).Read(0x10bcf590, 0x10bd2000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
/usr/local/go/src/net/http/transfer.go:643 +0x118
net/http.(_bodyEOFSignal).Read(0x10bcf5c0, 0x10bd2000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
/usr/local/go/src/net/http/transport.go:1616 +0x20c
bufio.(_Reader).fill(0x10bd8f6c)
/usr/local/go/src/bufio/bufio.go:97 +0x1c4
bufio.(_Reader).ReadSlice(0x10bd8f6c, 0x1096400a, 0x0, 0x0, 0x0, 0x0, 0x0)
/usr/local/go/src/bufio/bufio.go:328 +0x264
bufio.(_Reader).ReadLine(0x10bd8f6c, 0x0, 0x0, 0x0, 0x109da000, 0x0, 0x0)
/usr/local/go/src/bufio/bufio.go:357 +0x60
github.com/duyhtq/maya/firego.(_Firebase).Watch.func1(0x10c52000, 0x10a12f20, 0x109610c0)
/home/ubuntu/gows/src/github.com/duyhtq/maya/firego/watch.go:148 +0x234
created by github.com/duyhtq/maya/firego.(*Firebase).Watch
/home/ubuntu/gows/src/github.com/duyhtq/maya/firego/watch.go:246 +0x468

goroutine 47 [select, 122 minutes]:
net/http.(*persistConn).readLoop(0x10a06690)
/usr/local/go/src/net/http/transport.go:1185 +0xbf0

goroutine 50 [chan receive, 122 minutes]:
github.com/duyhtq/maya/firego.(_Firebase).Watch.func1.1(0x10a12f20, 0x10d943a0, 0x10d94398, 0x10c52000)
/home/ubuntu/gows/src/github.com/duyhtq/maya/firego/watch.go:124 +0x30
created by github.com/duyhtq/maya/firego.(_Firebase).Watch.func1
/home/ubuntu/gows/src/github.com/duyhtq/maya/firego/watch.go:131 +0x144

trap 0x0
error 0x0
oldmask 0x0
r0 0x0
r1 0x2b14
r2 0x6
r3 0x326ff450
r4 0x326ff910
r5 0x326ff450
r6 0x0
r7 0x10c
r8 0x1
r9 0x0
r10 0x114e1d40
fp 0x720120
ip 0x10c
sp 0x326fead8
lr 0xb6dbaebf
pc 0xb6dac926
cpsr 0x20000030
fault 0x0
exit status 2

StartAtValue or EndAtValue with string starting with "+" plus symbol

Figured out that these methods StartAtValue and EndAtValue, returns a empty map[] if the string starts with the plus signal "+". Discovered this because my app does a simple query just to check if an existing data exists like cellphones (with international codes starting with "+").

func DataExist(k string, d string) bool {
	var v map[string]interface{}
	uRef, err := fdb.Ref("users/")
	if err != nil {
		fmt.Printf("Error")
		return false
	}
	if err := uRef.StartAtValue(d).EndAtValue(d).LimitToFirst(1).OrderBy(k).Value(&v); err != nil {
		log.Fatal(err)
		return false
	}
	if len(v) == 0 {
		return false
	}
	return true
}

Calling it:

p := fbdb.DataExist("phone", "+5561999999999")
log.Println("Phone Exist? ", p)

   returns -> **Phone Exist?  false** 

If you put any value after "+" like "+newstring" and update your DB, it also does not work. I've tried with other symbols like "=,#,-" and they seems to work.

Prevent loop to crash when EventTypeError

Hello,

What is the best way to prevent the loop to make the program crash when receiving an EventTypeError message please ?

        // Watch
	notifications := make(chan firego.Event)
	err := firebase.Watch(notifications)
	if err != nil {
		shared.Log.Fatalln("Notifications have stopped because an error occured :", err)
	}
	defer firebase.StopWatching()

        // Parse the events
	for event := range notifications {
		helpers.ParseEvent(event)
	}

I my ParseEvent, if an EventTypeError happen, I just display a message, but the program crashes anyway.

Regards.

Firebase Transaction Function Request

Firebase has a function transaction(transactionUpdate, onComplete, applyLocally) which you can view here.

The function's purpose is explained here:

When working with data that could be corrupted by concurrent modifications, such as incremental counters, you can use a transaction operation.

This is extremely useful and would be a great feature to firego as it is currently unsupported as far as I believe.

Any thoughts?

Timing out on Watch notifications

Is there an easy way to trace the firego package? I had the program working but recently starting hitting this error condition.

New to golang and using the nest api so the issue is probably mine but was looking to better isolate and understand the issue - 30 seconds should be long enough but it's very possible that some of my libraries did change on an update of my system as well.

Error when using `go dep`

I'm using dep for dependency management and when I run dep ensure or dep ensure -add gopkg.in/zabawaba99/firego.v1 it gives the following error

ensure Solve(): No versions of github.com/zabawaba99/firego met constraints: 
v1: Could not introduce github.com/zabawaba99/firego@v1, as its subpackage github.com/zabawaba99/firego/sync is missing. (Package is required by gopkg.in/zabawaba99/firego.v1@v1.) 
v1: Could not introduce github.com/zabawaba99/firego@v1, as its subpackage github.com/zabawaba99/firego/sync is missing.
(Package is required by gopkg.in/zabawaba99/firego.v1@v1.)

I apologize if this is an issue with dep but I after quite a bit of digging I haven't been able to find out why this would be happening with just this package. Might be low priority but it sure is frustrating.

Thanks!

autoreconnect

it looks like firego doesn't auto-reconnect AFTER the device lost internet for a long period and then got internet back again (say, after 30 mins). how do you get around this so that firego client automatically reconnects after the device goes online again? thanks.

error "Unauthorized request." when change to new private key

Just don't know what happen I've use firego for firebase realtime database and everything work fine in development but on production, I've generate new service key and replace that key with the same file that I've use in development. Then to authenticate there are no problem but I've got "error" : "Unauthorized request." when try to read data from realtime databsae

any idea ?

OrderBy example returns a Go map which does not preserve order

The example in the README.md for the orderBy attribute deserialises the result into a map.
If the user needs to display the results in ascending order, he cannot rely on the map, since the ordering of the items retrieved when looping through it is not preserved.

Parameter Escape to Boolean values

Please update func escapeString under guery.go to support bool values

func escapeString(s string) string {
	_, err := strconv.ParseInt(s, 10, 64)
	if err != nil {
		return `"` + strings.Trim(s, `"`) + `"`
		_,err =strconv.ParseBool(s)
		if err!=nil{
			return `"` + strings.Trim(s, `"`) + `"`
		}
	}
	return s
}

Fix Build/Code Coverage

  • Configure travis to build this repo
  • Configure Coveralls to build repo and report code coverage

Firebase.Ref(pagth): concurrent map iteration and map write

I think I called Ref very fast in succession?

fatal error: concurrent map iteration and map write

goroutine 173 [running]:
runtime.throw(0x451fc4e, 0x26)
	/usr/local/Cellar/go/1.9.4/libexec/src/runtime/panic.go:605 +0x95 fp=0xc42004f1b8 sp=0xc42004f198 pc=0x402c435
runtime.mapiternext(0xc42004f308)
	/usr/local/Cellar/go/1.9.4/libexec/src/runtime/hashmap.go:778 +0x6f1 fp=0xc42004f250 sp=0xc42004f1b8 pc=0x400bba1
runtime.mapiterinit(0x44c2f80, 0xc42016a120, 0xc42004f308)
	/usr/local/Cellar/go/1.9.4/libexec/src/runtime/hashmap.go:768 +0x270 fp=0xc42004f2b8 sp=0xc42004f250 pc=0x400b250
github.com/zabawaba99/firego.(*Firebase).copy(0xc420064300, 0x0)
	/Users/gabe/go/src/github.com/zabawaba99/firego/firebase.go:217 +0x1c5 fp=0xc42004f378 sp=0xc42004f2b8 pc=0x43c3875
github.com/zabawaba99/firego.(*Firebase).Ref(0xc420064300, 0xc420018180, 0x30, 0x1, 0x1, 0xc420018180)
	/Users/gabe/go/src/github.com/zabawaba99/firego/firebase.go:109 +0x35 fp=0xc42004f400 sp=0xc42004f378 pc=0x43c29f5

StopWatching() -> panic: send on closed channel

Seen on 7c8d46a after calling Firebase.StopWatching()

panic: send on closed channel

goroutine 124 [running]:
panic(0x53ece0, 0xc420a5a9b0)
  /usr/local/Cellar/go/1.7/libexec/src/runtime/panic.go:500 +0x1a1
.../vendor/github.com/zabawaba99/firego.(*Firebase).Watch.func1(0xc4200e8fc0, 0xc420a5a309, 0xc4200e9020)
  /.../vendor/github.com/zabawaba99/firego/watch.go:99 +0x70
created by sigma/vendor/github.com/zabawaba99/firego.(*Firebase).Watch
  /.../vendor/github.com/zabawaba99/firego/watch.go:100 +0x132

Errors always return as EOF

Whenever there is an error of any kind (including auth errors, similar to issue #78), I get the following event and then the watch channel closes:
firego.Event{Type:"event_error", Path:"", Data:(*errors.errorString)(0xc82000a160), rawData:[]uint8(nil)}

Printing out event.Data gives:
&errors.errorString{s:"EOF"}

This same EOF error occurs for 'permission denied' as well as missing indexOn errors. The only way for me to differentiate between them is to execute the same request via cURL.

Watch does not work with large result sets

Hi,

in your eventSplit() function your are not handling the case, if the scanner doesn't find a '\n' at the end. Which can happen, when the results sets are bigger. But fixing that does not work either, because with larger result sets you can even run into a case where the scan exceeds MaxScanTokenSize. One way to fix it, is to use bufio#Reader.ReadLine(). Do you want to fix it yourself or would you accept my patch for it?

BTW: Thanks for publishing the code. :)

Stefan

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.