CodementorIO/rest-firebase

How to initialise firebase with server start.

Opened this issue · 15 comments

I am trying to integrate firebase and I used this code in config/initializers/firebase.rb

require 'rest-firebase'

f = RestFirebase.new :site => 'https://xxxx-11111.firebaseio.com/',
      :secret => 'xxxxx1651x1xxx61x16x616xxxx',
      :d => {:auth_data => 'something'},
      :log_method => method(:puts),
      :timeout => 10,
      :max_retries => 3,
      :retry_exceptions =>
      [IOError, SystemCallError, Timeout::Error],
      :error_callback => method(:p),
      :auth_ttl => 82800,
      :auth => false # Ignore auth for this example!

    es = f.event_source('/')

    es.onerror do |error|
      puts "ERROR: #{error}"
    end



es.onreconnect do
  !!@start # always reconnect unless stopping
end

es.onmessage do |event, data|
  puts "EVENT: #{event}, DATA: #{data}"
end

puts "Starting..."
@start = true
es.start

 rd, wr = IO.pipe

 Signal.trap('INT') do # intercept ctrl-c
   puts "Stopping..."
   @start = false      # stop reconnecting
   es.close            # close socket
   es.wait             # wait for shutting down
   wr.puts             # unblock main thread
 end

 rd.gets               # main thread blocks here

but when i try to start my rails server: rails s -b 0.0.0.0 -p 3030

the console stuck at:

rails s -b 0.0.0.0 -p 3030

=> Booting Puma
=> Rails 5.0.4 application starting in development on http://0.0.0.0:3030
=> Run `rails server -h` for more startup options
Starting...

and need to press Ctrl+C to start the puma. but by this firebase stop working. how I can integrate firebase listener with rails so whenever I start the server firebase starts with it.

The code you pasted, was designed to run as a standalone process. If you want to run it inside another process, you should not use those rd and wr pipes, and you should also remove signal handling (i.e. Signal.trap)

I don't know if puma has a hook where it would be called before shutting down. Make sure you still stop Firebase there, otherwise you might interrupt some requests, corrupting data.

If you can't find where you could handle that in puma, perhaps you could try to use at_exit. I am not sure if that would work well though. Something like:

at_exit do
  puts "Stopping..."
  @start = false      # stop reconnecting
  es.close            # close socket
  es.wait             # wait for shutting down
end

Note that all the codes were just examples. It's bad to use @start here. You should wrap the client in your own class.

Let me know if you have other questions.

Awesome! Working fine.

well worked in puma mode but not working in Daemon mode.

Could you be more specific? What didn't work? What is Daemon mode? Is it a special mode in puma? Or are you running a standalone daemon process without involving puma?

working fine when i start the server with this command: rails s
but not worked when I start the server with rails s -d

What exactly didn't work? Did you see any error? Which code are you using?

this code is /config/initializers/firebase.rb file so whenever I start the server it initialise the firebase too..
require 'rest-firebase'

f = RestFirebase.new :site => 'https://xxxx-xxxxx.firebaseio.com/',
  :secret => 'xxxx7x878xux87x8hx9yhx98xh87h98xh',
  :d => {:auth_data => 'something'},
  :log_method => method(:puts),
  :timeout => 10,
  :max_retries => 3,
  :retry_exceptions =>
  [IOError, SystemCallError, Timeout::Error],
  :error_callback => method(:p),
  :auth_ttl => 82800,
  :auth => false # Ignore auth for this example!

es = f.event_source('/Notifications')

es.onerror do |error|
  puts "ERROR: #{error}"
end



es.onreconnect do
  !!@start # always reconnect unless stopping
end

es.onmessage do |event, data|
  # puts "EVENT: #{event}, DATA: #{data}"

  path =  data['path'].split('/')
  if path.last.nil?

  else
    if event == 'put' && !data['data'].nil?
      dialog_id = path.last
      badge_count = data['data']['badge_count']
      push_token = data['data']['push_token']
      platform_status = data['data']['platform_status']
      user_id = data['data']['user_id']
      message = data['data']['message']
      username = data['data']['name']
      chat_dialog_id = data['data']['chat_dialog_id']
      if Notification.firebase_push(message, user_id, badge_count, push_token, platform_status, dialog_id, chat_dialog_id, username)
        base_uri = 'https://xxxx-xxxxx.firebaseio.com/'
        secret_key = 'asfafasfasfafasf78a6sf78aysfas'
        firebase = Firebase::Client.new(base_uri, secret_key)
        delete = firebase.delete("Notifications/#{dialog_id}", {})
      else
        p 'wong check'
      end


    end
  end
end

@start = true
es.start
puts "Starting..."

at_exit do
  puts "Stopping..."
  @start = false      # stop reconnecting
  es.close            # close socket
  es.wait             # wait for shutting down
end 

ok, so what didn't work?

Note that this is using threads underneath, and if puma would ever fork, and you preload the application, then the forked processes would not have the threads doing the work. So if it is forking, you should not preload the application.

es.start
not called when I start the server with -d.

Did the file ever got loaded?

Yes Sir,
=> Booting Puma
=> Rails 5.0.4 application starting in development on http://0.0.0.0:3030
=> Run rails server -h for more startup options
Starting...

Since you saw "Starting...", I think es.start should be called. Why did you think that it's not called?

can you please provide a full tutorial on how to implement and how to deploy?

I'll try to write something when I have time. Thanks for asking.

Thank You, will wait for your reply.