Now let's apply what we learned
over the last lectures in our shop project
we built throughout this course.
Here, I got that project with React Navigation 5 integrated.
So after this other section where I show
how to upgrade to React Navigation 5.
And I haven't changed anything else.
So this is the app as we know it, running on the simulators.
And there we can, of course, create an account
with some credentials here.
First of all, I need to sign up.
And now here, we can add products and so on.
Now, my idea is that when we add a product here,
we actually don't just store the product
with all the data we're uploading thus far.
At the moment, when we create a product,
we are sharing title, description, imageUrl,
price and ownerId.
But instead, besides sharing all of that,
I also want to add the push token of the device
of the user who added this product.
So the push token of the seller,
I wanna add that to the product as well.
Why?
So that when we fetch the product data,
we can also download the push token
that belongs to a product.
And whilst we won't show this to the other users,
we'll use it in code to ensure that when an order is placed,
when we add an order, we don't just store that order data
in the database, but we also send a push notification
to the owner of the product that was just ordered,
letting him or her know that the product was ordered.
That's my idea here.
That of course means that we'll have to analyze the items
that are in the cart.
And then we'll send a push notification
for every product, basically.
That's my idea.
So, for that to ensure this works,
we first of all need to prepare this project
for push notifications.
That means that we first of all should go to app.json
and add that android entry here
where we set useNextNotificationsApi to true.
That's what I showed you before
in the other lectures as well.
We also need to ask the user for permission.
So, the question is where we wanna do that, of course.
Since it's the creator of a product
who should receive push notifications,
I will ask for permission right before we create
a new product.
So, we have our user, our EditProductScreen,
where we create a new product.
And there, in the end, we trigger an action.
In the products.js file here
we'll trigger this createProduct action.
And now my idea is that I ask for permission here,
I then also fetch the token here
and then we can add the token to the outgoing data
that's being sent to the server.
So therefore, let's first of all expo install
the expo-notifications package and also expo-permissions.
And then let's use both just as we learned it
over the lectures in this module.
So with that installed, here in create product,
before we do anything else,
we wanna use the notifications API.
And for that we have to import everything as notifications
from expo-notifications.
And let's also already import everything as permissions
from expo-permissions.
And with these two APIs imported,
in createProduct we can use notifications
to get our ExpoPushToken.
However, as you know, we don't directly wanna do that.
Instead we first of all wanna check the permission status.
So we should use permissions and get the information
about the notifications permission.
This returns a promise,
and since we're in the async function here,
we can simply await it.
Now what we'll get back is that statusObj
which has that status property
that tells us whether a permission was granted or not.
So we can check if statusObj.status is maybe not granted,
which means we are not having permissions yet,
then we wanna use the permissions API again
to ask for the notifications permission with this code.
And that's all just what we had before,
now just with asyn await, instead of then.
But other than that, it's the same.
And here we'll again get our statusObj.
Now, since we would have a name clash here,
I'll name this here: updatedStatusObj.
And of course, here we should also await,
because that is asynchronous and it returns a promise.
So, at this point of time here,
we can now check if updatedStatusObj
has a status that's not equal to granted.
And if that's the case, we know we won't be able to
send push notifications.
And that is absolutely fine.
I will simply create a token variable here,
and set token equal to null here to make it very clear
that we simply don't have a token here.
Actually, let's not name it token,
because we already used that name.
Let's name it pushToken, because that is what
we wanna retrieve in the end.
So, we set this to null here.
If we absolutely didn't get permission,
because there is nothing we can do in that case,
because we then just don't have permission
to send push notifications.
It is what it is.
But in the else case, that this is granted,
in that case we can set our pushToken equal to
notifications.getExpoPushTokenAsync.
And of course, that's a promise.
So we should await this.
And of course, we don't directly get the token,
instead we get an object which has a data field,
if you recall, and so we could wrap this here into brackets
and call data on that.
That simply means that first of all
this promise is resolved,
then we call data on the resolved object
after we awaited the promise, hence the value in data,
which we then store in the pushToken variable.
So here we'll have our pushToken, which we need.
Now, when we have that, we can continue.
And since we use await, this code will only execute
once that all finished.
This line, of course, should be removed now.
And now, with the data we sent to the server,
we don't just send the title, description, the ownerId,
but also the ownerPushToken.
And that will be our pushToken here.
And that's either null, or it is our token we got from expo.
So now, whenever we create a new product,
ideally we're able to send our pushToken along.
Now getting that token and all of that
won't work on simulators, as you learned.
So therefore, I'll save this and again test this
on my real iPhone.
So again, I got my app booting up here,
and I just logged in with the user we created.
And now, under Admin, I will create a new product.
A Push Token Test.
Now we need a Image Url.
And I just grabbed some random image.
And I'll enter a price here and a description.
And confirm this.
And I'm getting an error that updatedStatusObj wasn't found.
And that makes sense, because actually I'm setting this here
in this if check, but then I'm using it outside
of this if check, so of course this has the wrong scope.
Little oversight from my side.
We can fix this by actually reusing statusObj
up here instead by turning it into a variable with let.
Then here we simply set our statusObj to a new value
and then we use statusObj again here in this if check.
Now the scope is right and this will work.
So let's try this again.
A push test.
Insert that image which I picked.
Insert a price and a description.
This is a test.
Then close this, confirm this.
And now this seems to work.
I added my product.
And what will be interesting now is our database.
Here's my Firebase database, so the backend we're using.
And a new product was added here.
And indeed, here we see our PushToken.
Again, I added an overlay over my actual device token,
but this is now a push token which allows us
to send a notification to the user who created this product.
So now, let's work on that other part
and let's make sure that we indeed do send a notification
once we actually order a product.