Wednesday 28 June 2017

Ionic 3 and Angular 4: Adding Custom Fonts like Open Sans and Font Awesome.

We all know that Ionic is the useful framework for building HTML 5 mobile applications. It is mainly designed for the front end. When it comes to look and feel of the Ionic website, you have to work more on your application branding standards. Ionic default icons are not up to current market standards. This tutorial is all about how to add custom downloaded fonts like open sans and font awesome for icons into the Ionic application. Let’s see how you use customized fonts in your Ionic website.

Ionic 3 and Angular 4:Create a Welcome Page with Login and Logout.

Read more »
Share:

Thursday 22 June 2017

Introducing fastlane precheck: Submit your app to the app store with confidence

Doug Stevenson
Joshua Liebowitz
Software Engineer

We've all been in this situation before: you work tirelessly to build a great app, you spend countless hours beta testing and fixing bugs, and you even put together a comprehensive marketing plan in time for your app's launch. Months of anticipation finally culminate when you submit your app to the app store… but instead of celebrating the new release, you find out that your app didn't meet the right criteria for listing so it got rejected 😱.

There's nothing quite as deflating as tripping at the finish line.

App store guidelines can be complicated and hard to remember because they're constantly changing, but developers still need to follow them in order to get their apps approved. Sometimes, these guidelines get overlooked or lost in the shuffle of all the other important pre-launch tasks. To help you avoid unnecessary delays and rejection, we're excited to introduce fastlane precheck for iOS apps! You can count on us to remember the rules so you can submit your app with confidence.

Review your app in seconds to save days of delays

Often, apps get rejected from app stores because of simple, solvable issues with their metadata (such as title, description, changelog, keywords, etc.). Once rejected, you have to resubmit your app and it can take days before it's reviewed again. This wastes time and can throw off your schedule.

Instead of risking rejection or painstakingly auditing your own metadata, you can now use fastlane precheck to save you the time and hassle. fastlane will review your app for the most common causes of rejection 👍.

For example, we'll check your metadata to ensure it follows iOS app store rules such as:

  1. No other platforms are mentioned in the description
  2. There are no curse words in your copy
  3. No placeholder text is left
  4. No URLs are broken

If we detect any issues, we'll flag them for you so you can resolve them before you submit your app to the app store. And since fastlane can automatically download your app's metadata, this whole process takes only seconds!

More exciting things ahead

fastlane precheck is the first new tool we've added to our app automation toolkit since joining Google - and we have even more exciting updates planned! Now that we've settled into our new home, we can't wait to move fastlane forward with our passionate community of iOS and Android developers.

In the meantime, install fastlane or update your version of fastlane (just run `fastlane update_fastlane`) to try precheck and submit your app with confidence and peace of mind 🚀.

This post originally appeared on the Fabric blog. fastlane is an app deployment and automation toolset that joined Firebase in January as part of the Fabric acquisition.
Share:

Ionic 3 and Angular 4: PHP Restful API User Authentication for Login and Signup.

Here is the continued article on my previous post for creating a welcome page with login and logout. Today’s post explains how to implement login authentication system for your AngularJS applications. It will show you how to log in with a user and store the user session, so it deals with token based authentication. Since we are using token based authentication, it protects if any unauthorized request is made and notices for a new login if required. This makes your application’s authentication to be more secured compared with any other authentication system. Every user details will be stored in an external database and a PHP based API is used in the backend for handling this authentication. Hope you’ll find it more easily using this as your authentication system in your AngularJS projects. Let’s look into the live demo and follow the below code.

Ionic 3 and Angular 4:Login and Signup with PHP Restful API.

Read more »
Share:

Wednesday 21 June 2017

Keep your promises when using Cloud Functions for Firebase!

Doug Stevenson
Doug Stevenson
Developer Advocate

Many Firebase developers focus on their apps alone, usually for Android, iOS, or the Web (or all three!). If you're like me, and you spend most of your time on the client side, it can be a hassle to also deal with any backend components. Now that we have Cloud Functions for Firebase, it's super easy and fun to write and deploy backend code in JavaScript without having to manage servers. Personally, my comfort zone is with Android. So, to get acquainted with Cloud Functions, I spent some time brushing up on my JavaScript and learning node.js, which Cloud Functions uses to run backend code.

Enter the Promise

As part of that period of ramping up, I learned a new way of managing asynchronous work in JavaScript. If you've had experience working with JavaScript in the browser or with Cloud Functions, you may already be familiar with a class called Promise. A promise is a very common way to handle async work. The closest concept for Android developers is the Task API that you sometimes use when dealing with Firebase APIs.

A promise lets you respond to a unit of work that's executing asynchronously, such as a database write or a network request. Cloud Functions understand promises; if you want a function to stay alive during async work, you can do this by returning a promise from the function (except for HTTP/S triggers, which require a response sent to the client). When you return a promise, be sure to return a promise that is "resolved" after all asynchronous work performed in that function is fully complete. Many developers have found this video from the Firebase channel on YouTube very helpful for understanding how promises work with Cloud Functions:

In the video, Jen describes two main ways of dealing with promises. First, there's using the then() method on a promise to chain items of work in sequence, where the next item of work depends on the results from the previous item. Second, there's Promise.all() which creates a new promise that resolves after multiple items of work happening in parallel are all complete. Between these two mechanisms, you can manage most work that normally occurs in a function. When the work is complete, you return the final promise from the function so that the Cloud Functions environment knows when to clean up.

ECONNRESET got you down?

For simple functions, this works out pretty easily. But many of you (including myself) have discovered that complicated functions can be really difficult to manage when there's a lot of work (with lots of promises) going on. One of the symptoms of mismanaged promises is seeing the following error in the function log in the Firebase console:

Error: read ECONNRESET

This error could mean a few different things. In some cases it could be a bug in a client library. In other cases, it's a symptom of a common mistake when dealing with promises.

If a function is terminated before its network connections are finished, that means those open connections could be forced to close, leaving an ECONNRESET in the log. Here's a situation when that can occur.

Imagine you want to start three items of async work, and the work is kicked off in a function called doSomeAsync(), which returns a promise that's resolved upon completion, and you return the promise from the third task like this:


doSomeAsync(x)
doSomeAsync(y)
return doSomeAsync(z)

Returning a Promise from the function is good. But Cloud Functions needs a promise that resolves when all of the work is fully complete. If we don't have a guarantee that the last item of work will always finish after the other two, then Cloud Functions may clean up the function prematurely, causing problems. Instead, we need to combine all of the promises from all of the work into a new promise that resolves only after all of the others resolve, like this:


const promise_x = doSomeAsync(x)
const promise_y = doSomeAsync(y)
const promise_z = doSomeAsync(z)
return Promise.all([promise_x, promise_y, promise_z])

If you're not tracking every single item of asynchronous work that you kick off in a function, you could see the dreaded ECONNRESET error in your log, and things may not work the way you expect. It really can take some diligence to keep all your promises!

If you want to see an example of a more complicated function, I have an open source tic-tac-toe web game that I wrote for a session I gave at Google I/O '17 that talks about how it was built entirely with Firebase.

For more tutorials and content about Cloud Functions, and other Firebase products, be sure to check out the Firebase channel on YouTube and the Firebase Blog.

Share:

Tuesday 20 June 2017

Relive the Firebase + Fabric party at WWDC17

Megan Krilanovich
Megan Krilanovich
Program Manager

Just two weeks ago, we hosted our party at WWDC to celebrate app development with the iOS community. We were thrilled to meet many of you including tons of talented developers from Apple, Uber, Spotify, Tinder, and more. With over a thousand RSVPs, it was amazing to see the excitement among the community!

Since we can't travel back in time, here are some highlights so you can relive the night of fun.

The entrance

We love our customers - so what better way to show our appreciation then rolling out the red carpet? We also made sure to have friendly hosts to greet you at the door and security guards as rigorous as an IDS.

The experience

We noticed most of you felt right at home at Forager. It was great to see all of you mingle with each other and with us to and discuss app development and all the WWDC announcements of the day. Whether we found you at the stand up tables, or hanging out on the blue and yellow sofas: everyone was having fun!

Thank you to all those who submitted creative names for our cocktails and congrats to the winners! The Minty Multithread and Nulltonic Expression were hits and went great with the finger-licking good appetizers.

The fun

Many of you shared your passion projects with other developerson the flat screens throughout the venue. And we couldn't keep ourselves from grinning at some of the pics from the paparazzi style photo booth. See all the photo booth moments here.

Over half of you played AppShip3000 - our flagship cooperative multiplayer game. You either flexed your knowledge muscle, or learned a thing or two about Firebase. And many of you also saw one of our engineers live-code an app. Was it a hotdog? Or not? What do you think?

The swag

Since it's dub dub, we crafted custom designed iPhone protective cases for you to take home (in case cocktails and holding-onto-phones don't mix). Stylish tees included as usual.

Thank you to all those who joined us for the night - we were glad to share all the laughter with you. Check out our full photo album. (photos credit: Yvonne TNT)

Here's to next year!

In their words:

Share:

Monday 19 June 2017

Managing Users from the Firebase Admin Java SDK

Diego Giorgini
Hiranya Jayathilaka
Software Engineer


As the developer or the administrator of an app built on Firebase, you may need to perform various user management tasks. These include:

  • Provisioning new user accounts for your app
  • Updating existing user accounts
  • Manually verifying and enabling user accounts
  • Disabling or deleting user accounts
  • Querying user profile information to populate dashboards or compile reports

The Firebase Admin SDK provides a powerful API for performing these kinds of user management tasks from privileged environments. Using the Admin SDK, you can program these capabilities directly into your admin consoles, dashboards and other backend services. Unlike the Firebase client SDK, the Admin SDK is initialized with a service account credential, which grants the SDK elevated privileges necessary to perform user management operations.

This is not a brand new feature. The Firebase Admin Node.js SDK has had a user management API for a while. However, we are happy to announce that this API is now also available in our Admin Java SDK starting from version 5.1.0. This is one of the most requested features for the Admin Java SDK, and we are certain many Firebase app developers are going to find it useful.

The Java user management API closely mirrors its Node.js counterpart. Specifically, it consists of five new methods:

  • getUser()
  • getUserByEmail()
  • createUser()
  • updateUser()
  • deleteUser()

Following code snippet shows how to use some of these new methods in practice. In this example we retrieve an existing user account, and update some of its attributes:

final FirebaseAuth auth = FirebaseAuth.getInstance();
Task task = auth.getUserByEmail("editor@example.com")
.addOnSuccessListener(userRecord -> {
System.out.println("Successfully fetched user data: " + userRecord.getUid());
UpdateRequest update = userRecord.updateRequest()
.setDisabled(false) // Enable the user account
.setEmailVerified(true); // Set the email verification status
auth.updateUser(update);
})
.addOnFailureListener(e -> {
System.err.println("Error fetching user data: " + e.getMessage());
});

You can learn more about the Firebase user management API from the Admin SDK documentation. Additionally, head over to our Github repoto see how it is implemented. (Yes, it's all open source!). You can also help us further improve this API by providing us feedback and reporting issues. As always, we are open to all sorts of contributions including pull requests to our codebase. Happy coding with Firebase!

Share:

Monday 12 June 2017

Angular 4.2 Now Available

Angular version 4.2 has been released. This is a minor release following our announced adoption of Semantic Versioning, meaning that it contains no breaking changes and that it is a drop-in replacement for 4.x.x.

What's new?
  • Angular Forms now includes validators for min and max attributes
  • You can now bootstrap a component directly by passing an element reference to the bootstrap method of an ApplicationRef
  • Improved i18n tooling including MissingTranslationStrategy and location notes in xliff2 files
  • We've begun laying the foundation for testing AOT components, which will become possible in a future release
  • New compiler flag alwaysCompileGeneratedCode is available opt-in, and will be turned on by default in the future

For the complete list of features and bugfixes please see the changelog.

Angular Animations
We've added a huge number of new features to make working with Animations easier and more powerful. Some of these features were previewed at ng-conf 2017.

  • Configure options and set input variables within animations
  • Define reusable animations using animation()
  • Query for inner elements within animations using query()
  • Stagger multiple elements within an animation using stagger()
  • Enable queried elements to trigger their own animations
  • Orchestrate a full-blown animation when routes change
  • Programmatically build/control an animation using AnimationBuilder
A new angular.io
Today we are also releasing a new angular.io website! We've rebuilt the site's infrastructure, architecture, and design using Angular under the hood. The site has the same content as before, but now the code and content live directly in the angular/angular repo under aio.

This site is the first step of a journey in two ways. First, we hope this rebuild will make it easier to accept public contributions to our documentation in the future. We're in the process of refactoring many of our documentation pages, and are excited to get your feedback and improvements after these changes launch. We're planning on adding an inline link to "improve this doc" on every page which will take you directly to GitHub where you can suggest changes.

Second, we hope that in in the future this site will serve as an example of some of the best practices for building Angular applications. Today the site is a Progressive Web Application and includes a Service Worker that increases repeat load performance.
Share:

Ionic 3 and Angular 4:Create a Welcome Page with Login and Logout.

Most of the mobile applications starts with welcome page with login and signup buttons. A proper login or signup redirects to application home page and there you can navigate to different pages and finally you can end up with a logout action. Today’s tutorial is all about this. Here I am using AngularJS 4 and Ionic 3. The combination of AngularJS and Ionic in handling login is a straight forward process. This design is already explained in my previous posts using ReactJS navigations. Lets see how to set a starting page using Ionic 3 and AngularJS4 and learn basic understanding of how the navigation works.

Ionic 3 and Angular 4:Create a Welcome Page with Login and Logout.

Read more »
Share:

Friday 9 June 2017

Making Dynamic Links Easier

 Jumana Al Hashal
Jumana Al Hashal
Product Manager

Firebase Dynamic Links give you a single link that can send users either to your iOS or Android app, if they have it installed, or to the appropriate listing in the App Store or on Google Play, if they don't. Even better than that, Dynamic Links will deep link your users to the content they were looking for, even if they had to install the app in the process.

We've been working hard over the last year to make this experience smoother and more powerful for both developers and users, and we're happy to bring the latest set of improvements to developers in our iOS and Android SDKs.

Building Dynamic Links, Dynamically

Creating Dynamic Links through the Firebase Console was great for promotional campaigns, but we heard from our developers that they needed to be able to create user-to-user sharing campaigns programmatically from within their app.

To help you do just that, we've added support for generating both long and short dynamic links to the iOS and Android Firebase SDKs, which makes it quicker and easier to support these kind of use cases:

iOS:


guard let deepLink = URL(string: "https://mydomain.com/page?param=value") else { return }

let components = DynamicLinkComponents(link: deepLink, domain: domain)

let iOSParams = DynamicLinkIOSParameters(bundleID: bundleID)
iOSParams.minimumAppVersion = minVersion
components.iOSParameters = iOSParams

// Build the dynamic link
let link = components.url

// Or create a shortened dynamic link
components.shorten { (shortURL, warnings, error) in
if let error = error {
print(error.localizedDescription)
return
}

// TODO: Handle shortURL.
}

Android:


String deepLink = "https://mydomain.com/page?param=value";

DynamicLink.Builder builder = FirebaseDynamicLinks.getInstance()
.createDynamicLink()
.setDynamicLinkDomain(domain)
.setAndroidParameters(new DynamicLink.AndroidParameters.Builder()
.setMinimumVersion(minVersion)
.build())
.setLink(deepLink);

// Build the dynamic link
DynamicLink link = builder.buildDynamicLink();

// Or create a shortened dynamic link
builder.buildShortDynamicLink()
.addOnSuccessListener(new OnSuccessListener() {
@Override
public void onSuccess(ShortDynamicLink shortDynamicLink) {
//
}
});

New Android API

We've also rebuilt the Android API from the ground up to make it easier to handle incoming Dynamic Links into your app, with the new FirebaseDynamicLinks class. You can add the new library by adding the following to your build.gradle:

compile "com.google.firebase:firebase-dynamic-links:11.0.0"

Then processing an incoming Dynamic Link is easy in your launched activity:


FirebaseDynamicLinks.getInstance().getDynamicLink(getIntent())
.addOnSuccessListener(
new OnSuccessListener() {
@Override
public void onSuccess(PendingDynamicLinkData data) {
if (data == null || data.getLink() == null) {
// No FDL pending for this app, don't do anything.
return;
}

Intent launchIntent = data.getUpdateAppIntent(MainActivity.this);
if (launchIntent != null) {
startActivity(launchIntent); // launch upgrade flow.
}

Uri deepLink = dynamicLink.getLink();
String myAppItemId = deepLink.getQueryParameter("myAppItemId");
// TODO(developer): Display content for myAppItemId here!
}
});

As always, if you have any questions or feedback on the new API, please reach out through any of the channels on our support page.

Share:

Wednesday 7 June 2017

Serving dynamic content with Cloud Functions on Firebase Hosting

Michael Bleigh
Michael Bleigh
Engineer, Firebase Hosting

Three years ago, we launched Firebase Hosting to make it easier for developers to deliver fast, engaging experiences on the web. Two months ago, we launched the beta of Cloud Functions for Firebase to let developers write custom backend logic without having to worry about servers or infrastructure. More recently at Google I/O, we brought Firebase Hosting and Cloud Functions together to provide a flexible set of tools to build Progressive Web Apps with world-class scale and performance.

You can connect an HTTPS Cloud Function to your Firebase Hosting app by adding a rewrite to the firebase.json configuration for your project:


{
"hosting": {
"rewrites": [
{"source": "/function/**", "function":"myFunction"}
]
}
}

Once connected, matching requests seamlessly proxy to your Cloud Function (in the example above, a function named myFunction). This one-line change enables exciting new capabilities for Firebase Hosting users including:

  1. Server-Side Rendering. Until now, Firebase Hosting has only served static content. Now you can serve dynamic content using industry-standard libraries like Express, while still leveraging a lightning-fast global CDN cache.
  2. Custom APIs. With Cloud Functions and Firebase Hosting, you can create custom API endpoints on your own domain, avoiding the overhead of cross-origin requests. Plus, with a few extra lines of code you can authorize your endpoints through Firebase Auth.
  3. User-Generated Web Content. For the first time, Firebase Hosting can generate content compatible with AMP, Twitter Cards, and more without requiring a deploy. This means your Firebase Hosting apps can be more shareable and more searchable than ever before.

For Cloud Functions users, you can now run functions on an SSL-secured custom domain and get powerful caching to avoid unnecessary executions.

To get started using Cloud Functions on Firebase Hosting for your own Firebase project, take a look at our documentation. You can also learn more in our I/O session: Building Fast Web Experiences with Firebase Hosting.

Share:

Friday 2 June 2017

Content Moderation with Cloud Functions for Firebase

Nicolas Garnier
Nicolas Garnier
Developer Programs Engineer

In apps that allow users to post public content - for instance in forums, social networks and blogging platforms - there is always a risk that inappropriate content could get published. In this post, we'll look at ways you can automatically moderate offensive content in your Firebase app using Cloud Functions.

The most commonly used strategy to moderate content is "reactive moderation". Typically, you'll add a link allowing users to report inappropriate content so that you can manually review and take down the content that does comply with your house rules. You can better prevent offensive content from being publicly visible and complement your reactive moderation by adding automated moderation mechanisms. Let's see how you can easily add automatic checks for offensive content in text and photos published by users on your Firebase apps using Cloud Functions.

We'll perform two types of automatic content moderation:

Text moderation where we'll remove swearwords and all shouting (e.g. "SHOUTING!!!").

Image moderation where we'll blur images that contain either adult or violent content.

Automatic moderation, by nature, needs to be performed in a trusted environment (i.e. not on the client), so Cloud Functions for Firebase is a great, natural fit for this. Two functions will be needed to perform the two types of moderation.

Text Moderation

The text moderation will be performed by a Firebase Realtime Database triggered function named moderator. When a user adds a new comment or post to the Realtime Database, a function is triggered which uses the bad-words npm package to remove swear words.We'll then use the capitalize-sentencenpm package to fix the case of messages that contain too many uppercase letters (which typically meaning users are shouting). The final step will be to write back the moderated message to the Realtime Database.

To illustrate this we'll use a simple data structure that represents a list of messages that have been written by users of a chat room. These are made of an object with a text attribute that gets added to the /messages list:


/functions-project-12345
/messages
/key-123456
text: "This is my first message!"
/key-123457
text: "IN THIS MESSAGE I AM SHOUTING!!!"

Once the function has run on the newly added messages, we'll add two attributes: sanitized which is true when message has been verified by our moderation function and moderated which is trueif it was detected that the message contained offensive content and was modified. For instance, after the function runs on the two sample messages above we should get:


/functions-project-12345
/messages
/key-123456
text: "This is my first message!",
sanitized: true,
moderated: false
/key-123457
text: "In this message I am shouting."
sanitized: true,
moderated: true

Our moderator function will be triggered every time there is a write to one of the messages. We set this up by using the functions.database().path('/messages/{messageId}').onWrite(...)trigger rule. We'll moderate the message and write back the moderated message into the Realtime Database:


exports.moderator = functions.database.ref('/messages/{messageId}')
.onWrite(event => {
const message = event.data.val();

if (message && !message.sanitized) {
// Retrieved the message values.
console.log('Retrieved message content: ', message);

// Run moderation checks on on the message and moderate if needed.
const moderatedMessage = moderateMessage(message.text);

// Update the Firebase DB with checked message.
console.log('Message has been moderated. Saving to DB: ', moderatedMessage);
return event.data.adminRef.update({
text: moderatedMessage,
sanitized: true,
moderated: message.text !== moderatedMessage
});
}
});

In the moderateMessage function, we'll first check if the user is shouting and if so fix the case of the sentence and then remove all bad words using the bad-words package filter.


function moderateMessage(message) {
// Re-capitalize if the user is Shouting.
if (isShouting(message)) {
console.log('User is shouting. Fixing sentence case...');
message = stopShouting(message);
}

// Moderate if the user uses SwearWords.
if (containsSwearwords(message)) {
console.log('User is swearing. moderating...');
message = moderateSwearwords(message);
}

return message;
}

// Returns true if the string contains swearwords.
function containsSwearwords(message) {
return message !== badWordsFilter.clean(message);
}

// Hide all swearwords. e.g: Crap => ****.
function moderateSwearwords(message) {
return badWordsFilter.clean(message);
}

// Detect if the current message is shouting. i.e. there are too many Uppercase
// characters or exclamation points.
function isShouting(message) {
return message.replace(/[^A-Z]/g, '').length > message.length / 2 || message.replace(/[^!]/g, '').length >= 3;
}

// Correctly capitalize the string as a sentence (e.g. uppercase after dots)
// and remove exclamation points.
function stopShouting(message) {
return capitalizeSentence(message.toLowerCase()).replace(/!+/g, '.');
}

Note: the bad-words package uses the badwords-list package's list of swear words which only contains around 400 of these. As you know the imagination of the user out there has no limit, so this is not an exhaustive list and you might want to extend the bad words dictionary.

Image Moderation

To moderate images we'll set up a blurOffensiveImages function that will be triggered every time a file is uploaded to Cloud Storage. We set this up by using the functions.cloud.storage().onChange(...) trigger rule. We'll check if the image contains violent or adult content using the Google Cloud Vision API. The Cloud Vision API has a feature that specifically allows to detect inappropriate content in images. Then if the image is inappropriate we'll blur the image:


exports.blurOffensiveImages = functions.storage.object().onChange(event => {
const object = event.data;
const file = gcs.bucket(object.bucket).file(object.name);

// Exit if this is a move or deletion event.
if (object.resourceState === 'not_exists') {
return console.log('This is a deletion event.');
}

// Check the image content using the Cloud Vision API.
return vision.detectSafeSearch(file).then(data => {
const safeSearch = data[0];
console.log('SafeSearch results on image', safeSearch);

if (safeSearch.adult || safeSearch.violence) {
return blurImage(object.name, object.bucket, object.metadata);
}
});
});

To blur the image stored in Cloud Storage, we'll first download it locally on the Cloud Functions instance, blur the image with ImageMagick, which is installed by default on all instances, then re-upload the image to Cloud Storage:


function blurImage(filePath, bucketName, metadata) {
const filePathSplit = filePath.split('/');
filePathSplit.pop();
const fileDir = filePathSplit.join('/');
const tempLocalDir = `${LOCAL_TMP_FOLDER}${fileDir}`;
const tempLocalFile = `${LOCAL_TMP_FOLDER}${filePath}`;
const bucket = gcs.bucket(bucketName);

// Create the temp directory where the storage file will be downloaded.
return mkdirp(tempLocalDir).then(() => {
console.log('Temporary directory has been created', tempLocalDir);
// Download file from bucket.
return bucket.file(filePath).download({
destination: tempLocalFile
});
}).then(() => {
console.log('The file has been downloaded to', tempLocalFile);
// Blur the image using ImageMagick.
return exec(`convert ${tempLocalFile} -channel RGBA -blur 0x8 ${tempLocalFile}`);
}).then(() => {
console.log('Blurred image created at', tempLocalFile);
// Uploading the Blurred image.
return bucket.upload(tempLocalFile, {
destination: filePath,
metadata: {metadata: metadata} // Keeping custom metadata.
});
}).then(() => {
console.log('Blurred image uploaded to Storage at', filePath);
});
}

Cloud Functions for Firebase can be a great tool to reactively and automatically apply moderation rules. Feel free to have a look at our open source samples for text moderation and image moderation.

Share: