Showing Mail Statistics Using Firebase In Badgeyay

In this blog post I will show how we implemented mail statistics on the admin dashboard of Badgeyay. The problem is that we cannot send a request to an external API from firebase cloud functions in free plan and secondly we have to them bypass the call to realtime database and design a logic to sort out the details from the realtime database using python admin sdk. So, our approach in solving this is that we will use the realtime database with the cloud functions to store the data and using the firebase admin sdk will sort the entries and using binary search will count the statistics efficiently..

Procedure

  1. Configuring the database URL in admin SDK
firebase_admin.initialize_app(cred, {
      ‘storageBucket’: ‘badgeyay-195bf.appspot.com’,
      ‘databaseURL’: ‘https://badgeyay-195bf.firebaseio.com’
  })

 

  1. Write the mail data in realtime database using cloud function on promise resolvement
function writeMailData(uid, state, reason) {
if (state === ‘success’) {
  db.ref(‘mails’)
    .push()
    .set({

      …
    }, err => {
      …

    });
}
}

 

  1. Fetching the mail data from the realtime database in python admin sdk
def get_admin_stat():
  mail_ref = firebasedb.reference(‘mails’)
  mail_resp = mail_ref.get()

  …
  curr_date = datetime.datetime.utcnow()
  prev_month_date = curr_date – relativedelta(months=1)
  last_three_days_date = curr_date – relativedelta(days=3)
  last_seven_days_date = curr_date – relativedelta(days=7)
  last_day_date = curr_date – relativedelta(days=1)
  …

 

This will fetch the current date and them generates the relative dates in past. Then it filters out the data using a for loop and a comparison statement with the date to get the count of the mails. Those count is then passed into a dict and sent through schema.

  1. Fetching the mail stats in admin index panel
mails    : await this.get(‘store’).queryRecord(‘admin-stat-mail’, {})

 

  1. Showing mails on the index page

class=“six wide column”>
          div class=“ui fluid center aligned segment”>
              h3 class=“ui left aligned header”>
                  Messages
              h3>
              div class=“ui divider”>div>
              h3 class=“ui header”>
                  No. of Sent Mails
              h3>
              table class=“ui celled table”>
                  tbody>
                      tr>
                          td> In last 24 hourstd>
                          td class=“right aligned”>
                              {{model.mails.lastDayCount}}
                          td>
                      tr>
                      tr>
                          td>In last 3 daystd>
                          td class=“right aligned”>
                              {{model.mails.lastThreeDays}}
                          td>
                      tr>
                      tr>
                          td> In last 7 days td>
                          td class=“right aligned”>
                              {{model.mails.lastSevenDays}}
                          td>
                      tr>
                      tr>
                          td> In last 1 month td>
                          td class=“right aligned”>
                              {{model.mails.lastMonth}}
                          td>
                      tr>
                  tbody>
              table>
          div>
      

 

PR to the issue: https://github.com/fossasia/badgeyay/pull/1163

Benefits of the approach

This approach is best in the case, when we only are using a subset of services firebase offers and do not want to pay for the services that are not required by the system.

Resources

Continue Reading

Badges Search Functionality In Admin

Badgeyay is a badge generator service developed by FOSSASIA community for generating badges for conferences and events. Project is separated into frontend that is designed in EmberJS and backend that is created in Flask. Now The Badges tab in admin shows the total badges that are in the system. Along with different meta attributes like Badge creator name, date and other data. The main problem is that it doesn’t provide a way to search the badges from the admin panel. In this blog post i am going to explain about integrating badge search functionality in admin.

Procedure

  1. Integrating form element for searching
<form class=“ui form” {{action ‘findBadges’ on=“submit”}}>
                  

class=“field”>
                      

class=“ui action input”>
                          {{input type=“text” autocomplete=‘off’ value=user placeholder=“Search Badges…”}}
                          
                      


                  </div>
              </form>

 

  1. Main difficulty is to send the data to route components as we can’t pass the props, like we pass in components. The workaround is to send the query as route parameter.
findBadges() {
    var userTerm = this.get(‘user’);
    this.transitionToRoute(‘admin.badges.list’, userTerm);
  }

 

  1. Extracting the query parameter and making request to backend
if (params.badge_status === ‘all’) {
    filter.state = ‘all’;
  } else if (params.badge_status === ‘created’) {
    filter.state = ‘created’;
  } else if (params.badge_status === ‘deleted’) {
    filter.state = ‘deleted’;
  } else {
    filter.filter = params.badge_status;
  }

 

  1. Creating query in controller to fetch the data for the same.
if ‘filter’ in args.keys():
      badges = base_query.filter(User.username.contains(args[‘filter’]))
      badges = badges.paginate(page, app.config[‘POSTS_PER_PAGE’], False)
      schema = AdminBadgeSchema(many=True)
      return jsonify(schema.dump(badges.items).data)

 

Resources

  • Flask Sqlalchemy documentation for query – Link
  • Pull Request for the same – Link
  • Ember Guide – Link
Continue Reading
Close Menu