Urigo / Ionic2CLI-Meteor-WhatsApp

WhatsApp Clone tutorial with Ionic 2.0 CLI and Meteor Server
https://www.angular-meteor.com/tutorials/whatsapp2/ionic/setup
163 stars 185 forks source link

New tutorial #40

Open dotansimha opened 7 years ago

dotansimha commented 7 years ago

@Urigo @DAB0mB

Still missing (this is the order of work):

Future:

Urigo commented 7 years ago

@dotansimha @DAB0mB did you add tests for most steps?

DAB0mB commented 7 years ago

@Urigo Not yet. We were re-innovating the project and the architecture and API were constantly changing, and only recently few services and directives came in, therefore BDD was off the table. Certainly we should add it to the milestone. We also need to upload meteor-client and @types/meteor-collection-hooks.

johnsonc commented 7 years ago

@dotansimha @Urigo : Hi, Will the Socially app which now resides as a branch here as well be documented? Would have really loved to try that out.. Visited its tutorial page 5 times and no updates! Will you guys be ever covering it?? If yes then Yay!! Thanks much!

Urigo commented 7 years ago

@johnsonc we are merging all the chapters into one single, great tutorial. It will cover everything and will also be easier for us to maintain. We will release that very soon

johnsonc commented 7 years ago

Thank you very much!

On 25-Jan-2017 1:12 PM, "Uri Goldshtein" notifications@github.com wrote:

@johnsonc https://github.com/johnsonc we are merging all the chapters into one single, great tutorial. It will cover everything and will also be easier for us to maintain. We will release that very soon

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/Urigo/Ionic2CLI-Meteor-WhatsApp/issues/40#issuecomment-275040054, or mute the thread https://github.com/notifications/unsubscribe-auth/ABIBhk4_PCC6tRPWslTAH3Uye1NBTIqXks5rVvzRgaJpZM4LqgM2 .

AndyDorman commented 7 years ago

I am currently finishing up the exiting whatsapp tutorial as a great learning tool for Ionic2, Angular2 and Typescript (and Mongo...I am a long-time SQL person). After I finish I plan to do it again with your revised and improved tutorial. Thanks for adding unit tests for the new version. As an enterprise developer (in other languages) I am a big believer that automated testing can keep you out of a lot of trouble in the long run.

gianpaj commented 7 years ago

don't forget adding screenshots along the way. it really helps understanding what you're getting into and what will be the output at the end 😄

DAB0mB commented 7 years ago

@gianpaj We will, we're right now working on writing some quality manuals, and once we finished we will take some pictures. There's a lot to look forward to!

AndyDorman commented 7 years ago

a tiny bit of feedback as I step through the updated whatsapp+socially tutorial:

step 1.2 copying the webpack.js file it says "We will copy it to a newly created config dir using the following command:" However, from looking at the repository and the command it looks like webpack.js is copied to the app root directory.

Slavrix commented 7 years ago

Hey, just seeing if there is any ETA on the unit testing examples at all, or if there is a branch where it is being worked on that I can take a look at.

Also, are the client tests going to be done for the ionic2 cli as well as the meteorcli ?

darkbasic commented 7 years ago

Is there any guide which explains how to effectively contribute to the tutorial? I did a couple of pull requests for the tutorial, but without the knowledge on how to generate the various steps (diffs, etc..) it's hard to make "production ready" commits... I'm far from being a Meteor expert (but I know a bit more about Angular), but if you need a couple more eyes to review the new tutorial let me know and I will gladly help.

Urigo commented 7 years ago

if you want to see how we create the tutorial and help, check out this repository. this is the tool we use and we would love to get help in updating both docs and code to the latest versions

darkbasic commented 7 years ago

Thanks, I will have a look and try to contribute! I have lots of fixes I would like to submit, currently the tutorial is broken in many subtle ways (for example you will need to use cordova Telerik-Verified-Plugins/ImagePicker instead of cordova wymsee/cordova-imagePicker to be able to use the ImagePicker on Android6+). I found dozens of these corner cases, it seems it will be an hard job the keep the tutorial updated with such fast moving technologies. By the way congratulations for the great work, angular-meteor is shaping really well and at a fast pace :)

Urigo commented 7 years ago

@darkbasic thank you very much! just know that you can always contact me and the team directly with any questions, we would love to increase the people who are able to contribute to the tutorial and library

darkbasic commented 7 years ago

Pending fixes from darkbasic

darkbasic commented 7 years ago

It took plenty of time to implement Facebook authentication, because Meteor.loginWithFacebook() didn't work out of the box and I had to check Meteor's source code to understand how accounts and oauth were implemented. So I realized that the magic happens on the Meteor server side. So I did set my oauth redirect_uri to the port where the Meteor server is running and not the port where the Ionic server is running. But as I imagined it still wasn't enough because such a way it wasn't possible to retrieve the credentials from the Session Storage (plus some other issues with cross origin). So I decided to put a nginx proxy in front of both Ionic and Meteor server:

server {
    listen       80;
    server_name  domain.tld;

    location / {
        proxy_pass http://domain.tld:8100;
    }
    location /_oauth {
        proxy_pass http://domain.tld:3000;
    }
    location /packages {
        proxy_pass http://domain.tld:3000;
    }
}

Such a way if I connect to http://domain.tld:80 everythings works flawlessly. Since you are way more skilled than me with the Angular + Ionic + Meteor combo, what do you think about my workaround? Is there a better solution? It is possible to find more info about the issue on StackOverflow: https://stackoverflow.com/questions/37114997/how-does-the-meteor-accounts-oauth-workflow-happen/

By the way if someone is interested I also implemented a 100% client-side self-contained solution (no routing) before deciding it was worth investigating what happened with accounts-facebook:

loginFacebook(): Promise<any> {
  return new Promise((resolve, reject) => {
    if (this.platform.is('cordova')) {
      var browserRef = this.inAppBrowser
        .create(`https://www.facebook.com/v2.9/dialog/oauth?client_id=${CLIENT_ID}&redirect_uri=${ROOT_URL}/callback&response_type=token&scope=email`, "_blank", "location=no,clearsessioncache=yes,clearcache=yes");

      const exitSubscription: Subscription = browserRef.on("exit").subscribe((event) => {
        console.error("The Facebook sign in flow was canceled");
        reject("The Facebook sign in flow was canceled");
      });

      browserRef.on("loadstart").subscribe((event) => {
        console.log(event);
        if ((event.url).indexOf(`${ROOT_URL}/callback`) === 0) {
          console.log(event.url);
          exitSubscription.unsubscribe();
          browserRef.close();
          var responseParameters = ((event.url).split("#")[1]).split("&");
          var parsedResponse = {};
          for (var i = 0; i < responseParameters.length; i++) {
            parsedResponse[responseParameters[i].split("=")[0]] = responseParameters[i].split("=")[1];
          }
          if (parsedResponse["access_token"] !== undefined && parsedResponse["access_token"] !== null) {
            console.log(parsedResponse);
            resolve(parsedResponse);
          } else {
            console.error("Problem authenticating with Facebook");
            reject("Problem authenticating with Facebook");
          }
        }
      });
    }
  });
}

InAppBrowser works fine with Cordova, but it isn't compatible with Browser. See my post here: https://forum.ionicframework.com/t/issue-inappbrowser-invalid-event-target/88548/15

AndyDorman commented 7 years ago

FWIW, I think using an nginx proxy for a web app is a good idea. Nginx is a solid front-end that can provide a good layer of security against exploits. It can also provide the SSL layer. We have used it as a proxy for php (Wordpress, Drupal, Horde) and perl web applications for many years.

OTOH how would Nginx work in the case of a cordova mobile app? I have no experience in that area.

Andy

On 05/04/2017 05:13 PM, Niccolò Belli wrote:

It took plenty of time to implement Facebook authentication, because |Meteor.loginWithFacebook()| didn't work out of the box and I had to check Meteor's source code to understand how accounts and oauth were implemented. So I realized that the magic happens on the Meteor server side. So I set my oauth redirect_uri to the port where the Meteor server is running and not the port where the Ionic server is running. But as I imagined it still wasn't enough because such a way it wasn't possible to retrieve the credentials from the Session Storage (plus some other issues with cross origin). So I decided to put a nginx proxy in front of both Ionic and Meteor server:

|server { listen 80; server_name domain.tld; location / { proxy_pass http://domain.tld:8100; } location /_oauth { proxy_pass http://domain.tld:3000; } location /packages { proxy_pass http://domain.tld:3000; } } |

Such a way if I connect to http://domain.tld:80 everythings worked flawlessly. Since you are way more skilled than me with the Angular + Ionic + Meteor combo, what do you think about my workaround? Is there a better solution?

By the way if someone is interested I also implemented a 100% client-side self-contained solution (no routing) before deciding it was worth investigating what happened with accounts-facebook:

|loginFacebook(): Promise { return new Promise((resolve, reject) => { if (this.platform.is('cordova')) { var browserRef = this.inAppBrowser .create(https://www.facebook.com/v2.9/dialog/oauth?client_id=${CLIENT_ID}&redirect_uri=${ROOT_URL}/callback&response_type=token&scope=email, "_blank", "location=no,clearsessioncache=yes,clearcache=yes"); const exitSubscription: Subscription = browserRef.on("exit").subscribe((event) => { console.error("The Facebook sign in flow was canceled"); reject("The Facebook sign in flow was canceled"); }); browserRef.on("loadstart").subscribe((event) => { console.log(event); if ((event.url).indexOf(${ROOT_URL}/callback) === 0) { console.log(event.url); exitSubscription.unsubscribe(); browserRef.close(); var responseParameters = ((event.url).split("#")[1]).split("&"); var parsedResponse = {}; for (var i = 0; i < responseParameters.length; i++) { parsedResponse[responseParameters[i].split("=")[0]] = responseParameters[i].split("=")[1]; } if (parsedResponse["access_token"] !== undefined && parsedResponse["access_token"] !== null) { console.log(parsedResponse); resolve(parsedResponse); } else { console.error("Problem authenticating with Facebook"); reject("Problem authenticating with Facebook"); } } }); } }); } |

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/Urigo/Ionic2CLI-Meteor-WhatsApp/issues/40#issuecomment-299324079, or mute the thread https://github.com/notifications/unsubscribe-auth/AAlC3Z25y-iQrv8dZZQ8j1FmrP0FX_B2ks5r2k2igaJpZM4LqgM2.

darkbasic commented 7 years ago

A Cordova mobile app runs locally, so AFAIK you can't access Facebook APIs anyway (unless you're testing). The solution would be to use something like cordova-plugin-facebook4 on Cordova. I tried it and it works flawlessly, but when trying to integrate it with Meteor using btafel:accounts-facebook-cordova I runned into problems on Android. I will have a look and try to find what's wrong.

darkbasic commented 7 years ago

I found the issue: https://github.com/Urigo/meteor-client-bundler/issues/23

btafel:accounts-facebook-cordova expects to be able to access Meteor.settings.public on the client, while Meteor.settings is undefined because meteor-client-bundler does not have the --settings parameter poiting to the settings file.

By the way I don't think that having to specify a settings parameter a second time in the client is a good design decision. Meteor should probably publish public settings using DDP instead. I don't know the innings so excuse me if I don't know how it's supposed to work.

darkbasic commented 7 years ago

While trying to fix yubozhao:meteor-link-accounts I also noticed that Meteor.isCordova is broken when using Ionic 2 + cordova run android (it always return false). It probably breaks tons of packages and should be fixed.

darkbasic commented 7 years ago

I don't like the end result because there is lots of code duplication between meteor-link-accounts and accounts-facebook, but that's how things were implemented and it would be very difficult to do otherwise without some kind of official support for accounts linking anyway.

Hopefully they will accept my patches upstream and there will be no need for a fork, but in the meantime here is my fork of meteor-link-accounts: https://github.com/darkbasic/meteor-link-accounts And my fork of accounts-facebook: https://github.com/darkbasic/accounts-facebook

Now meteor-angular has:

I'm still not ready to publish an updated version of the tutorial, but everything should be pretty straightforward if you read my previous comments (use an nginx proxy on Browser, etc..).

darkbasic commented 7 years ago

I implemented all the features I wanted to add to the tutorial, I'm looking into Tortilla right now.

darkbasic commented 7 years ago
$ tortilla create my-tutorial -m "How to create my app"
Cloning into '/tmp/tmp-7928rd3NtUZ13NNG'...
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
fs.js:584
  return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode);
                 ^

Error: ENOENT: no such file or directory, open '/tmp/tmp-7928rd3NtUZ13NNG/package.json'
    at Object.fs.openSync (fs.js:584:18)
    at Object.fs.readFileSync (fs.js:491:33)
    at overwriteTemplateFile (/usr/lib/node_modules/tortilla/src/essentials.js:153:28)
    at Object.createProject [as create] (/usr/lib/node_modules/tortilla/src/essentials.js:79:3)
    at Command.<anonymous> (/usr/lib/node_modules/tortilla/cli/tortilla:22:16)
    at Command.listener (/usr/lib/node_modules/tortilla/node_modules/commander/index.js:301:8)
    at emitTwo (events.js:106:13)
    at Command.emit (events.js:194:7)
    at Command.parseArgs (/usr/lib/node_modules/tortilla/node_modules/commander/index.js:615:12)
    at Command.parse (/usr/lib/node_modules/tortilla/node_modules/commander/index.js:458:21)

Am I doing something wrong?

DAB0mB commented 7 years ago

@darkbasic I've just changed the reference of Tortilla's skeleton to use https instead of ssh and released a new version that should do the trick, can you please re-install Tortilla and try again?

darkbasic commented 7 years ago

I'm starting to get familiar with Tortilla and I managed to edit a sub step: 1) tortilla step edit 6.3 2) Then I edit the source code 3) git add . 4) git commit --amend 5) git rebase --continue

Then I use a merge tool to rebase all the subsequent commits.

Unfortunately I cannot manage to edit a super step: 1) tortilla step edit 6 2) Then I edit .tortilla/manuals/templates/step6.tmpl 3) git add .tortilla/manuals/templates/step6.tmpl 4) git commit --amend 5) git rebase --continue 6) tortilla render manual --all (I also tried tortilla render manual 6 and tortilla render manual step6)

But unfortunately the view .tortilla/manuals/views/step6.md doesn't get updated :( Same problem when I try to create a new super step: the view doesn't get created.

Also how am I supposed to insert new sub steps into a previous step? For example let's say I want to add step 6.21 (last 6.x sub step is 6.20).

Last but not the least, how am I supposed to add a new super step (with several new sub steps) between two previous super steps? For example let's say I want to add the "Facebook auth" super step between step 7 and 8 (of course I will have to amend all subsequent steps to edit commit names, step numbers in the manuals templates, etc..).

DAB0mB commented 7 years ago

@darkbasic I will check the rendering thing, but it should work. If you would like to add a new sub step:

tortilla step edit 2.22
# stage your changes
tortilla step push -m "My changes"
git rebase --continue

If you would like to add a new super step:

tortilla step edit 2.22
# Stage your template changes
tortilla step tag -m "My new super step"
git rebase --continue

Tortilla will take care of managing the indexes :-)

darkbasic commented 7 years ago

Nice, sounds good. What about deleting a sub step, is it possible?

Regarding the rendering thing, am I supposed to get any kind of output from tortilla render manual? Because even if I type tortilla render manual non_existing_step I don't get any output at all.

DAB0mB commented 7 years ago

@darkbasic To remove a sub step either from the top or the middle of the stack, run:

$ tortilla step edit 2.22
$ tortilla step pop
$ git rebase --continue

Regards rendering, just check out the .tortilla/manuals/views dir, and you should see the output.

darkbasic commented 7 years ago

Yes I checked .tortilla/manuals/views but it doesn't create nor update the relative view, I don't know why. Is there anything I can do to debug why it doesn't work? I cloned the tutorial, edited a super step (simply added a couple of words in the corresponding template) and then generated all manuals. I expected to see an updated view, but it didn't happen...

DAB0mB commented 7 years ago

@darkbasic Clone a local copy of tortilla and install it using:

$ sudo npm install -g ../path/to/tortilla

Then try to run tortilla operations, and while you do so you can add console.log() to your tortilla so you could debug expected variable values. The manual.js module is the one whose responsible for rendering, so you should start checking the issue from there.

darkbasic commented 7 years ago

Looking at the source code I discovered that there is indeed an issue, but in the documentation :D I made a PR: https://github.com/Urigo/tortilla/pull/38

darkbasic commented 7 years ago

Rebasing everything to a brand new version with fresh packages is definitely the most painful part, especially when you didn't always use trailing commas and at the end of the merge you realize you missed a few commas in the middle of an array! Also, trailing commas really help merge tools to get their job done without user intervention, such a pity that json doesn't allow them :(

Anyway, I rebased everything and I'm starting to add new features. I even started to like Tortilla, it makes the task so much easier once you're used to it...

darkbasic commented 7 years ago

I found another pretty annoying issue: when rendering the view {{{diffStep 2.10}}} translates into step 2.1 instead of step 2.10. I don't have enough time to look at Tortilla's parser today and next week I will be in Spain, so I will be glad if you can have a look at it.

jycouet commented 7 years ago

Hi, Thank you for your https://github.com/Urigo/Ionic2CLI-Meteor-WhatsApp/issues/40#issuecomment-299324079 The only problem is that I'm not using ngix.

So I have my client side hosted on localhost:4200 speaking to my backend on loalhost:3000. How should I make this working?

Any ideas for this? Thank you

jycouet commented 7 years ago

Hi @darkbasic, Thanks again for all your comments. Even if I'n not sure about the nginx solution I'm giving a try... Do you have some special parameters for meteor apps? Because on my side (windows) it's really slow!

What should I put in settings.json?:

{
"runtime": {
    "DDP_DEFAULT_CONNECTION_URL": "http://domain.tld:80",
    "ROOT_URL": "http://domain.tld:80"
  }
}

And in the OAuth provider (github, facebook, google):

//for github
'http://domain.tld:80/_oauth/github?close'

@Urigo any other idea of implementation?


Thank you guys :1st_place_medal:

darkbasic commented 7 years ago

This is my meteor-client.config.json:

{
  "runtime": {
    "DDP_DEFAULT_CONNECTION_URL": "http://domain.tld:3000",
    "ROOT_URL": "http://domain.tld:80"
  },
  "import": [

  ]
}

I didn't find another easy solution which doesn't involve rewriting tons of code in the whole meteor stack. I'm in the process of writing a couple of new chapters, including Facebook. I will publish everything in a couple of weeks.

Urigo commented 7 years ago

@darkbasic could you please DM me somewhere? (Email, Slack, whatever... )

darkbasic commented 7 years ago

@Urigo I sent you an email on your github address.