Ad

Problem In Adding Data Through Admin.firestore()

My current firestore rules in my project:

service cloud.firestore {
  match /databases/{database}/documents {
    match /auth_url/{auth_doc} {
      allow read, write: if request.auth.uid != null;
    }
    match /nonauth_url/{nonauth_doc}{
      allow read, write: if false ;
    }
  }
}


auth_url collection is for authorized users and running perfectly (addition, creation, deletion etc of documents) and nonauth_url collection is for non authenticated users, by jquery post request through client.js I'm adding data by using admin.firestore() in my server (index.js) but in my cloud firestore section there is no data present there. Are my firestore rules wrong somewhere ?


client.js

function renderList(user){

    let db = firebase.firestore() ;
    
    stopListner = db.collection('auth_url').doc(user.email).onSnapshot( (doc) => {
        var objOfObj = doc.data() ;
        let newarrOfObjects = [] ;
        
        for( key in objOfObj){
            newarrOfObjects.push(Object.assign(objOfObj[key], {name: key})) ;
        }
        $('.container.urlsList').html('') ;
        newarrOfObjects.forEach( (obj, pos) => {
            if( obj.code != ''){

                $('.container.urlsList').append(`
                <div id="accordion${pos+1}" class="myUrlSlot">
                <div class="card">
                <div class="card-header d-flex flex-row align-items-center p-2">
                
                <button class="btn btn-outline-dark rounded-circle" data-toggle="collapse" data-target="#${pos+1}"><i class="fa fa-plus"></i></button>
                
                <div class="w-100 code font-weight-bold">
                ${obj.code}
                </div>
                
                <button data-edit-id="${pos+1}"class="btn btn-outline-primary edit rounded-circle"><i class="fa fa-pencil"></i></button>
                
                
                <button data-del-id="${pos+1}" class="btn btn-outline-danger del rounded-circle"><i class="fa fa-trash"></i></button>
                
                </div>
                <div id="${pos+1}" class="collapse info">
                <dl class='m-3'>
                <dt>Shortened URL</dt>
                <dd>${window.location.origin+ '/' + obj.code}</dd>
                <dt>Redirection URL</dt>
                <dd class="redirectUrl">${obj.redirectUrl}</dd>
                </dl>
                </div>
                </div>
                </div>
                `) ;
            }
        }) ;

        if( $('div.urlsList').children().length == 0){
            $('#emptyMsg').show() ;
         }
         else{
            $('#emptyMsg').hide() ;
         }

        
        // changing plus to minus vice-versa
        
        $('.collapse').on('show.bs.collapse', function(){
            $(this).parent().find('.fa-plus').removeClass('fa-plus').addClass('fa-minus') ;
        }).on('hidden.bs.collapse', function(){
            $(this).parent().find('.fa-minus').removeClass('fa-minus').addClass('fa-plus') ;
        }) ;
        
        
        // edit icon
        
        $('.edit').click(function(){
            let target_id = $(this).data('edit-id') ;
            bootbox.dialog({
                title: 'Change Redirection URL',
                centerVertical: true,
                closeButton: false,
                message: `
                <form id="changeUrlForm">
                <label for="inputUrl">Enter the New Url</label>
                <input type="url" class="form-control text-center" id="inputUrl" name="iurl" placeholder="Enter URL Here">
                </form>
                `,
                buttons: {
                    cancel: {
                        label: 'Cancel',
                        className: 'btn-danger'
                    },
                    ok: {
                        label: 'Ok',
                        className: 'btn-primary',
                        callback: function(){
                            $('#changeUrlForm').validate({
                                rules: {
                                    iurl: {
                                        required: true,
                                        url: true
                                    }
                                },
                                messages: {
                                    iurl: {
                                        url: 'Please enter a valid url with "http://" or "https://" first !!'
                                    }
                                }
                            }) ;
                            if( $('#changeUrlForm').valid()){
                                let newurl = $('#inputUrl').val() ;

                                var objToBeUpdated = `url${target_id}` ;

                                var updateObj = {} ;

                                updateObj[`${objToBeUpdated}.redirectUrl`] = newurl ;

                                db.collection('auth_url').doc(user.email).update(updateObj).then( () => {
                                    successAlert(`URL${target_id}'s redirection url updated successfully !!`) ;
                                }).catch( err => {
                                    errorAlert(err.code, err.message) ;
                                }) ;

                            }
                            else{
                                $('label.error').addClass('text-danger');
                                return false ;
                            }
                        }
                    }
                }
            }) ;
        }) ;
        
        // del icon
        
        $('.del').click(function(){
            let target_id = $(this).data('del-id') ;
            bootbox.confirm({
                message: 'Are you sure you want to delete this saved URL ?',
                centerVertical: true,
                closeButton: false,
                buttons: {
                    confirm: {
                        label: 'Yes',
                        className: 'btn-success'
                    },
                    cancel: {
                        label: 'No',
                        className: 'btn-danger'
                    }
                },
                callback: function(result){
                    if(result){
                        var updateObj = {
                            [`url${target_id}`]: {
                                code: '',
                                redirectUrl: ''
                            }
                        } ;

                        db.collection('auth_url').doc(user.email).update(updateObj).then(() => {
                            successAlert(`URL${target_id} deleted successfully !!`) ;
                        }).catch( err => {
                            errorAlert(err.code, err.message) ;
                        });
                    }
                }
            }) ;
        }) ;
    }, (err) => {
        errorAlert(err.code, err.message) ;
    }) ;
}





$(function(){
    // on authorization endering is working perfectly fine
  firebase.auth().onAuthStateChanged( user => {
      if( user ){
         if( firebase.auth().currentUser.emailVerified == false ){
            bootbox.dialog(verifyDialogSettings);
         }
         
         if( firebase.auth().currentUser.providerData[0].providerId === 'google.com'){
            $('.changePass, .beforechangePass').hide() ;
         }
         refreshMainPage( user ) ;
         // refreshUrls(user.email) ;
         console.log('signed in state') ;
         $('.login, #newurl, .mainTopic, .middle').hide() ;
         $('.signOutButton, .settings, .welcomemsg, .image, .description, .urlsList').show() ;
         
         // refresh the list
         
         renderList(user) ;
      }
      else{
         console.log('signed out state') ;
         $('.signOutButton, .settings, .welcomemsg, .image, .description, .urlsList, #emptyMsg').hide() ;
         $('.login, #newurl, .mainTopic, .middle').show() ;
      }
   });
   
   
   
$('.sendUrl').on('click', function(e){
      
      e.preventDefault() ;
      $('#nonauthForm').validate({
         rules: {
            url_nauth: {
               required: true,
               url: true
            }
         }
      }) ;

      if( $('#nonauthForm').valid()){
         $.post('/nonauth_url',{
               URL: $('#url').val()
            },function(code, status){
               if(status === 'success'){
                  $('#newurl').html(`
                  ${window.location.origin+ '/'+ code}
                  `)
               }
         }) ;
      }
      else{
         $('label.error').addClass('text-danger d-block mt-2');
      }  
}) ;




}) ;


index.js (server)

const functions = require('firebase-functions');
const admin = require('firebase-admin') ;
const express = require('express') ;
const urlId = require('shortid') ;

const sp = require('synchronized-promise') ;

const string = require('randomstring') ;

const serviceAccount = require('./url-shortner-xxxx.json') ;

const app = express() ;

admin.initializeApp({
   credential: admin.credential.cert(serviceAccount)
});

let db = admin.firestore() ;
let Data = db.collection('nonauth_url') ;

app.post('/nonauth_url', (req, res) => {
   
   let codeGenerated = 'n' + urlId.generate() ; // n for non-authenticated users
   
   let docname = 'doc-' + string.generate(4) ;
   
   let schema = {
      code: codeGenerated,
      url: req.body.URL,
      expiredAt: Date.now()+600000  // in milisceonds for 10min
   }
   
   let docRef = Data.doc(docname).set(schema) ;
   res.send(schema.code) ;
}) ;

exports.routeFunc = functions.https.onRequest(app) ;

res.send(schema.code) is sending back the code but not creating any docs under nonauth_url collection

Ad

Answer

Sending an HTTP response indicates the end of execution for a running function. You need to wait for the set() to complete before responding:

let docRef = Data.doc(docname).set(schema).then(() => {
  res.send(schema.code);
});
Ad
source: stackoverflow.com
Ad